命令 |
参数限制 |
内容 |
1 x y A |
1<=x,y<=N,A是正整数 |
将格子x,y里的数字加上A |
2 x1 y1 x2 y2 |
1<=x1<= x2<=N 1<=y1<= y2<=N |
输出x1 y1 x2 y2这个矩形内的数字和 |
3 |
无 |
终止程序 |
http://www.lydsy.com/JudgeOnline/problem.php?id=2683
把操作都离线出来,按x为第一关键字,y为第二关键字排序,按照读入顺序标记操作的顺序,在mid表示某个操作的时间,mid左边的操作就会影响mid右边的操作,如此进行cdq分治。查询操作拆成4个子操作。
还要继续巩固!
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define Q q[tot] const int maxn = 800000 +10; struct Node{ int x, y, A, no, belong, op; }q[maxn], tq[maxn]; int ans[maxn]; bool operator <(Node a, Node b){ if (a.x == b.x && a.y == b.y) return a.op < b.op; if (a.x == b.x) return a.y < b.y; return a.x < b.x; } #define lowbit(x) (x&(-x)) int N; int tree[maxn]; void update(int x, int v){ while(x <= N){ tree[x] += v; x += lowbit(x); } } int getsum(int x){ int sum = 0; while(x > 0){ sum += tree[x]; x -= lowbit(x); } return sum; } void solve(int l, int r){ if (l == r) return; int mid = (l+r)>>1; for(int i = l ;i <= r; i++){ if (q[i].no <= mid && q[i].op == 1) update(q[i].y, q[i].A); else if (q[i].no > mid && q[i].op == 2){ if (q[i].A){ ans[q[i].belong] += getsum(q[i].y); } else{ ans[q[i].belong] -= getsum(q[i].y); } } } for(int i = l; i <= r; i++){ if (q[i].no <= mid && q[i].op == 1) update(q[i].y, -q[i].A); } int l1 = l, l2 = mid + 1; for(int i = l; i <= r; i++){ if (q[i].no <= mid) tq[l1++] = q[i]; else tq[l2++] = q[i]; } for(int i = l; i <= r; i++){ q[i] = tq[i]; } solve(l, mid); solve(mid+1, r); } int main() { // freopen("data.in", "r", stdin); int T = 0, op, x, y, x1, y1, A, tot = 0; scanf("%d", &N); while(scanf("%d", &op) && op!=3){ if (op == 1){ scanf("%d%d%d", &x, &y, &A); q[++tot].op = 1; Q.x = x; Q.y = y; Q.A = A; Q.no = tot; } else{ scanf("%d%d%d%d", &x, &y, &x1, &y1); q[++tot].op = 2; Q.x = x-1; Q.y = y-1; Q.A = 1; Q.no = tot; Q.belong = ++T; q[++tot].op = 2; Q.x = x-1; Q.y = y1; Q.A = 0; Q.no = tot; Q.belong = T; q[++tot].op = 2; Q.x = x1; Q.y = y-1; Q.A = 0; Q.no = tot; Q.belong = T; q[++tot].op = 2; Q.x = x1; Q.y = y1; Q.A = 1; Q.no = tot; Q.belong = T; } } sort(q+1, q+1+tot); solve(1, tot); for(int i = 1; i <= T; i++){ printf("%d\n", ans[i]); } return 0; }