hdoj 4267 A Simple Problem with Integers 【线段树】

来源:互联网 发布:linux下查看用户 编辑:程序博客网 时间:2024/06/16 13:55

题目链接:hdoj 4267 A Simple Problem with Integers

A Simple Problem with Integers

Time Limit: 5000/1500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5030 Accepted Submission(s): 1586

Problem Description
Let A1, A2, … , AN be N elements. You need to deal with two kinds of operations. One type of operation is to add a given number to a few numbers in a given interval. The other is to query the value of some element.

Input
There are a lot of test cases.
The first line contains an integer N. (1 <= N <= 50000)
The second line contains N numbers which are the initial values of A1, A2, … , AN. (-10,000,000 <= the initial value of Ai <= 10,000,000)
The third line contains an integer Q. (1 <= Q <= 50000)
Each of the following Q lines represents an operation.
“1 a b k c” means adding c to each of Ai which satisfies a <= i <= b and (i - a) % k == 0. (1 <= a <= b <= N, 1 <= k <= 10, -1,000 <= c <= 1,000)
“2 a” means querying the value of Aa. (1 <= a <= N)

Output
For each test case, output several lines to answer all query operations.

Sample Input
4
1 1 1 1
14
2 1
2 2
2 3
2 4
1 2 3 1 2
2 1
2 2
2 3
2 4
1 1 4 2 1
2 1
2 2
2 3
2 4

Sample Output
1
1
1
1
1
3
3
1
2
3
4
1

题意:给定n个元素。有q次操作
1, a b k c 将区间[a, b]里面所有满足(i - a) % k == 0的元素A[i]增加c。
2, a 查询A[a]。

思路:发现k很小,我们可以预处理出以A[s]开头的k连续的所有元素,这些元素是同时增减的。更新的时候找到对应的s和区间[L, R],然后就是区间更新了。查询时累加所有线段树在a位置的元素,结果加上A[a]就好了。

AC代码:

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <map>#include <set>#define ll o<<1#define rr o<<1|1#define CLR(a, b) memset(a, (b), sizeof(a))using namespace std;typedef long long LL;typedef pair<int, int> pii;const int MAXN = 5*1e4 + 1;const int MOD = 1e9 + 7;struct Tree {    int l, r, sum, lazy;};Tree tree[10][10][MAXN<<1], tree1[MAXN<<2];void PushUp(int o, int k, int s) {    if(k == 1) {        tree1[o].sum = tree1[ll].sum + tree1[rr].sum;    }    else {        tree[k-1][s-1][o].sum = tree[k-1][s-1][ll].sum + tree[k-1][s-1][rr].sum;    }}void PushDown(int o, int k, int s) {    if(k == 1) {        if(tree1[o].lazy) {            tree1[ll].lazy += tree1[o].lazy;            tree1[rr].lazy += tree1[o].lazy;            tree1[ll].sum += tree1[o].lazy * (tree1[ll].r - tree1[ll].l + 1);            tree1[rr].sum += tree1[o].lazy * (tree1[rr].r - tree1[rr].l + 1);            tree1[o].lazy = 0;        }        return ;    }    k--; s--;    if(tree[k][s][o].lazy) {        tree[k][s][ll].lazy += tree[k][s][o].lazy;        tree[k][s][rr].lazy += tree[k][s][o].lazy;        tree[k][s][ll].sum += tree[k][s][o].lazy * (tree[k][s][ll].r - tree[k][s][ll].l + 1);        tree[k][s][rr].sum += tree[k][s][o].lazy * (tree[k][s][rr].r - tree[k][s][rr].l + 1);        tree[k][s][o].lazy = 0;    }}int a[MAXN];void Build(int o, int l, int r, int k, int s) {    if(k == 1) {        tree1[o].l = l; tree1[o].r = r;        tree1[o].sum = tree1[o].lazy = 0;    }    else {        tree[k-1][s-1][o].l = l; tree[k-1][s-1][o].r = r;        tree[k-1][s-1][o].sum = tree[k-1][s-1][o].lazy = 0;    }    if(l == r) {        return ;    }    int mid = (l + r) >> 1;    Build(o<<1, l, mid, k, s); Build(o<<1|1, mid+1, r, k, s);    PushUp(o, k, s);}void Update(int o, int L, int R, int v, int k, int s) {    if(k == 1) {        if(tree1[o].l == L && tree1[o].r == R) {            tree1[o].sum += (tree1[o].r - tree1[o].l + 1) * v;            tree1[o].lazy += v;            return ;        }    }    else {        if(tree[k-1][s-1][o].l == L && tree[k-1][s-1][o].r == R) {            tree[k-1][s-1][o].sum += (tree[k-1][s-1][o].r - tree[k-1][s-1][o].l + 1) * v;            tree[k-1][s-1][o].lazy += v;            return ;        }    }    PushDown(o, k, s); int mid;    if(k == 1) {        mid = (tree1[o].l + tree1[o].r) >> 1;    }    else {        mid = (tree[k-1][s-1][o].l + tree[k-1][s-1][o].r) >> 1;    }    if(R <= mid) Update(ll, L, R, v, k, s);    else if(L > mid) Update(rr, L, R, v, k, s);    else {        Update(ll, L, mid, v, k, s);        Update(rr, mid+1, R, v, k, s);    }    PushUp(o, k, s);}int Query(int o, int pos, int k, int s) {    if(k == 1) {        if(tree1[o].l == tree1[o].r) {            return tree1[o].sum;        }    }    else {        if(tree[k-1][s-1][o].l == tree[k-1][s-1][o].r) {            return tree[k-1][s-1][o].sum;        }    }    PushDown(o, k, s); int mid;    if(k == 1) {        mid = (tree1[o].l + tree1[o].r) >> 1;    }    else {        mid = (tree[k-1][s-1][o].l + tree[k-1][s-1][o].r) >> 1;    }    if(pos <= mid) return Query(ll, pos, k, s);    else return Query(rr, pos, k, s);}int main(){    int N;    while(scanf("%d", &N) != EOF) {        for(int i = 1; i <= N; i++) {            scanf("%d", &a[i]);        }        for(int k = 1; k <= 10; k++) {            for(int s = 1; s <= k; s++) {                Build(1, 1, N / k + 1, k, s);            }        }        int Q; scanf("%d", &Q);        while(Q--) {            int op;            scanf("%d", &op);            if(op == 1) {                int x, y, k, d;                scanf("%d%d%d%d", &x, &y, &k, &d);                int s = 0;                for(int i = 1; i <= k; i++) {                    if((x - i) % k == 0) {                        s = i; break;                    }                }                int yu = (y - x) % k; y -= yu;                int L = x / k; int R = y / k;                if(x % k) L++; if(y % k) R++;                //cout << L << ' ' << R << endl;                Update(1, L, R, d, k, s);            }            else {                int v; scanf("%d", &v);                int ans = 0;                for(int i = 1; i <= 10; i++) {                    for(int j = 1; j <= i; j++) {                        if((v - j) % i == 0) {                            int pos = v / i;                            if(v % i) pos++;                            ans += Query(1, pos, i, j);                            break;                        }                    }                }                printf("%d\n", ans + a[v]);            }        }    }    return 0;}
0 0