HDOJ5875(线段树) Function
Time Limit: 7000/3500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1701 Accepted Submission(s): 615
Problem Description
The shorter, the simpler. With this problem, you should be convinced of this truth.
You are given an array ).
You are given an array ).
Input
There are multiple test cases.
The first line of input contains a integer ), representing a query.
The first line of input contains a integer ), representing a query.
Output
For each query) on one line.
Sample Input
1
3
2 3 3
1
1 3
Sample Output
2
思路:用val[l],每次%上在[l+1,r]中下一个最小的值。
#include <cstdio> #include <algorithm> using namespace std; const int MAXN = 100005; struct Node{ int l, r, mn; }a[MAXN*3]; int n, m, val[MAXN]; void build(int rt, int l, int r) { a[rt].l = l; a[rt].r = r; if(l == r) { scanf("%d", &val[l]); a[rt].mn = val[l]; return ; } int mid = (l + r) >> 1; build(rt << 1, l, mid); build((rt << 1) | 1, mid + 1, r); a[rt].mn = min(a[rt<<1].mn, a[(rt<<1)|1].mn); } void query(int rt, int l, int r, int &x) { if(x == 0) return ; if(a[rt].mn > x) return ; if(a[rt].l == a[rt].r) { x %= a[rt].mn; return ; } int mid = (a[rt].l + a[rt].r) >> 1; if(r <= mid) { query(rt << 1, l, r, x); } else if(mid < l) { query((rt << 1) | 1, l, r, x); } else { query(rt << 1, l, mid, x); query((rt << 1) | 1, mid + 1, r, x); } } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d", &n); build(1, 1, n); scanf("%d", &m); while(m--) { int l, r; scanf("%d %d", &l, &r); if(l == r) { printf("%d ", val[l]); } else { int x = val[l]; query(1, l + 1, r, x); printf("%d ", x); } } } return 0; }