2683: 简单题
Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 1635 Solved: 661
[ 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
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 0x3f3f3f3f
struct 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;
}