BZOJ 2683: 简单题 离线+CDQ分治

来源:互联网 发布:淘宝飞机杯哪家好 编辑:程序博客网 时间:2024/05/31 18:30

2683: 简单题

Time Limit: 50 Sec  Memory Limit: 128 MB
Submit: 381  Solved: 163
[Submit][Status][Discuss]

Description

你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作:

 

命令

参数限制

内容

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

终止程序

Input

输入文件第一行一个正整数N。
接下来每行一个操作。
 

Output

对于每个2操作,输出一个对应的答案。
 

Sample Input

4
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3

Sample Output

3
5

HINT

1<=N<=500000,操作数不超过200000个,内存限制20M。

对于100%的数据,操作1中的A不超过2000。

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;}



0 0
原创粉丝点击