BZOJ2683 简单题 [KD-tree]

来源:互联网 发布:网络黑侠新书 编辑:程序博客网 时间:2024/06/06 20:20

2683: 简单题

Time Limit: 50 Sec  Memory Limit: 128 MB
Submit: 1635  Solved: 661
[Submit][Status][Discuss]

Description

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

 

命令

参数限制

内容

1 x y A

1<=x,y<=NA是正整数

将格子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。

Source


#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;#define MAXN 300100#define MAXT MAXN#define INF 0x3f3f3f3fstruct kdt_node{    int lc,rc,xmn,xmx,ymn,ymx,sum,x,y;}kdt[MAXT];int topt=0;inline void update(int now){    kdt[now].xmn=min(kdt[now].x,min(kdt[kdt[now].lc].xmn,kdt[kdt[now].rc].xmn));    kdt[now].xmx=max(kdt[now].x,max(kdt[kdt[now].lc].xmx,kdt[kdt[now].rc].xmx));    kdt[now].ymn=min(kdt[now].y,min(kdt[kdt[now].lc].ymn,kdt[kdt[now].rc].ymn));    kdt[now].ymx=max(kdt[now].y,max(kdt[kdt[now].lc].ymx,kdt[kdt[now].rc].ymx));}int x,y,v;void Add_kdt(int &now,int d=0){    if(!now){        now=++topt;        kdt[now].x=x;        kdt[now].y=y;        update(now);    }    kdt[now].sum+=v;    if (kdt[now].x==x&&kdt[now].y==y)return ;    if(!d){        if(x<=kdt[now].x)Add_kdt(kdt[now].lc,1-d);        else Add_kdt(kdt[now].rc,1-d);    }else{        if(y<=kdt[now].y)Add_kdt(kdt[now].lc,1-d);        else Add_kdt(kdt[now].rc,1-d);    }    update(now);}int x1,x2,y1,y2;int Query_kdt(int now,int d){    if(!now)return 0;    if(kdt[now].xmn>=x1 && kdt[now].xmx<=x2 && kdt[now].ymn>=y1 && kdt[now].ymx<=y2)return kdt[now].sum;    int ret=0;    if(kdt[now].x<=x2 && kdt[now].x>=x1 && kdt[now].y<=y2 && kdt[now].y>=y1)ret+=kdt[now].sum-kdt[kdt[now].lc].sum-kdt[kdt[now].rc].sum;    if(!d){        if(x1<=kdt[now].x)            ret+=Query_kdt(kdt[now].lc,1-d);        if(x2>kdt[now].x)            ret+=Query_kdt(kdt[now].rc,1-d);    }else{        if(y1<=kdt[now].y)            ret+=Query_kdt(kdt[now].lc,1-d);        if(y2>kdt[now].y)            ret+=Query_kdt(kdt[now].rc,1-d);    }    return ret;}inline void read(int &res){    static char ch;int flag=1;    while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;    while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=flag;}int main(){    int n,m,root=0,opt,lastans=0;    read(n);    kdt[0].xmn=kdt[0].ymn=INF;    kdt[0].xmx=kdt[0].ymx=-INF;    while(1){        read(opt);        if(opt==1){            read(x),read(y),read(v);            Add_kdt(root,0);        }else if (opt==2){            read(x1),read(y1),read(x2),read(y2);            printf("%d\n",lastans=Query_kdt(root,0));        }else break;    }    return 0;}

这里写图片描述