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;}
- HDOJ 4267 A Simple Problem with Integers(线段树)
- hdoj 4267 A Simple Problem with Integers 【线段树】
- A Simple Problem with Integers(线段树)
- A Simple Problem with Integers----线段树
- 线段树 A Simple Problem with Integers
- 线段树 A Simple Problem with Integers
- hdu 4267 A Simple Problem with Integers(线段树)
- HDU 4267 A Simple Problem with Integers (线段树)
- HDU 4267 A Simple Problem with Integers(线段树)
- HDU 4267 A Simple Problem with Integers (线段树)
- HDU 4267 A Simple Problem with Integers(线段树)
- HDOJ 4267 A Simple Problem with Integers 树状数组
- POJ 3468 A Simple Problem with Integers(线段树)
- [PKU] 3468 A Simple Problem with Integers -- 线段树
- POJ 3468 A Simple Problem with Integers (线段树)
- pku -- 3468 A Simple Problem with Integers(线段树)
- POJ 3468 A SIMPLE PROBLEM WITH INTEGERS(线段树)
- poj 3468 A Simple Problem with Integers 基础线段树
- SpringMVC源码剖析(二)- DispatcherServlet的初始化
- java基础(23)--强引用、弱引用、软引用、虚引用
- Java平台相关的换行符
- 安装jdk
- csuoj-1726-你经历过绝望吗?两次!
- hdoj 4267 A Simple Problem with Integers 【线段树】
- 【UVa】[11582]Colossal Fibonacci Numbers!
- C++ 语法学习
- C++ URLEncode编码
- Keepalived
- csuoj-1723-想打架吗?算我一个!所有人,都过来!
- 关于 Android 进程保活,你所需要知道的一切
- 北京林业大学“计蒜客”杯程序设计竞赛 网络赛
- 排序问题-归并排序