bzoj 4066: 简单题

来源:互联网 发布:全员加速中网络直播 编辑:程序博客网 时间:2024/06/10 09:10

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。
接下来每行一个操作。每条命令除第一个数字之外,
均要异或上一次输出的答案last_ans,初始时last_ans=0。

Output

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

Sample Input

4
1 2 3 3
2 1 1 3 3
1 1 1 1
2 1 1 0 7
3

Sample Output

3
5

HINT

数据规模和约定

1<=N<=500000,操作数不超过200000个,内存限制20M,保证答案在int范围内并且解码之后数据仍合法。

样例解释见OJ2683


新加数据一组,但未重测----2015.05.24

神TM加一组数据但未重测。特意加了一组卡不重构人的数据

kd-tree板子题,直接维护即可

重构的话我没用那种标准版的替罪羊树重构

设置了一个阀值,点数每次大于这个阀值的k倍就暴力重构一次

总觉得这么做有点不科学

----------------------------------------------------------------------------------------

各种被卡调了整整三天,一开始先弄了个动态加点的二维树套树,结果空间爆炸

各种姿势写kd-tree各种挂

#include<cmath>#include<cstdio>#include<string>#include<cstring>#include<algorithm>using namespace std;struct tree{int min[2],max[2],p[2];int ll,rr;int s,x;}tr[200001];int tot;int cmpd,rt;inline bool cmp(tree x,tree y){return x.p[cmpd]<y.p[cmpd]||x.p[cmpd]==y.p[cmpd]&&x.p[!cmpd]<y.p[!cmpd];}inline int min(int x,int y) {if(x<y)return x;return y;}inline int max(int x,int y) {if(x>y)return x;return y;}inline void up(int p){int L=tr[p].ll,R=tr[p].rr;if(L!=0){tr[p].min[0]=min(tr[L].min[0],tr[p].min[0]); tr[p].min[1]=min(tr[L].min[1],tr[p].min[1]);tr[p].max[0]=max(tr[L].max[0],tr[p].max[0]);tr[p].max[1]=max(tr[L].max[1],tr[p].max[1]);}if(R!=0){tr[p].min[0]=min(tr[R].min[0],tr[p].min[0]);tr[p].min[1]=min(tr[R].min[1],tr[p].min[1]);tr[p].max[0]=max(tr[R].max[0],tr[p].max[0]);tr[p].max[1]=max(tr[R].max[1],tr[p].max[1]);}tr[p].s=tr[L].s+tr[R].s+tr[p].x;}inline int build(int l,int r,int d){int mid=(l+r)/2;cmpd=d;nth_element(tr+l,tr+mid,tr+r+1,cmp);tr[mid].min[0]=tr[mid].p[0];tr[mid].min[1]=tr[mid].p[1];tr[mid].max[0]=tr[mid].p[0];tr[mid].max[1]=tr[mid].p[1];//tr[mid].s=0;if(l<mid)tr[mid].ll=build(l,mid-1,!d);elsetr[mid].ll=0;if(r>mid)tr[mid].rr=build(mid+1,r,!d);elsetr[mid].rr=0;up(mid);return mid;}int x1[2];inline int add(int p,int x,int y,int d,int xx){if(p==0){tot++;tr[tot].min[0]=tr[tot].max[0]=tr[tot].p[0]=x;tr[tot].min[1]=tr[tot].max[1]=tr[tot].p[1]=y;tr[tot].s=xx;tr[tot].x=xx;return tot;}if(tr[p].p[0]==x&&tr[p].p[1]==y){tr[p].s+=xx;tr[p].x+=xx;return p;}x1[0]=x;x1[1]=y;if(x<tr[p].min[0])tr[p].min[0]=x;else if(x>tr[p].max[0])tr[p].max[0]=x;if(y<tr[p].min[1])tr[p].min[1]=y;else if(y>tr[p].max[1])tr[p].max[1]=y;if(x1[d]<=tr[p].p[d])tr[p].ll=add(tr[p].ll,x1[0],x1[1],!d,xx);elsetr[p].rr=add(tr[p].rr,x1[0],x1[1],!d,xx);up(p);return p;}inline int ask(int p,int xx1,int yy1,int xx2,int yy2,int d){if(tr[p].s==0||p==0)return 0;if(xx1<=tr[p].min[0]&&yy1<=tr[p].min[1]&&tr[p].max[0]<=xx2&&tr[p].max[1]<=yy2)return tr[p].s;int x1[2],x2[2];x1[0]=xx1;x1[1]=yy1;x2[0]=xx2;x2[1]=yy2;int L=tr[p].ll,R=tr[p].rr;int ans=0;if(xx1<=tr[p].p[0]&&tr[p].p[0]<=xx2&&yy1<=tr[p].p[1]&&tr[p].p[1]<=yy2)ans+=tr[p].x;if(L&&tr[L].max[0]>=x1[0]&&tr[L].min[0]<=x2[0]&&tr[L].max[1]>=x1[1]&&tr[L].min[1]<=x2[1])if(x1[d]<=tr[p].p[d])ans+=ask(L,xx1,yy1,xx2,yy2,!d);if(R&&tr[R].max[0]>=x1[0]&&tr[R].min[0]<=x2[0]&&tr[R].max[1]>=x1[1]&&tr[R].min[1]<=x2[1])if(x2[d]>=tr[p].p[d])ans+=ask(R,xx1,yy1,xx2,yy2,!d);return ans;}inline int read(){    int x=0;char ch=getchar();    while(ch<'0'||ch>'9') ch=getchar();    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x;}struct quest{int x;int x1,y1,x2,y2;int xx;}xt[200001];int main(){//freopen("data.in","r",stdin); //freopen("data.out","w",stdout); int n;n=read();int x;int x1,y1,x2,y2;n=0;int m=0;x=read();int rt=0;tot=0;int last_ans=0; while(x!=3){if(x==1){m++;xt[m].x=x;xt[m].x1=read();xt[m].y1=read();xt[m].x2=read();}else{m++;xt[m].x=x;xt[m].x1=read();xt[m].y1=read();xt[m].x2=read();xt[m].y2=read();n++;}scanf("%d",&x);}int nt=(int)sqrt((double)n*log2((double)n))+1,i;nt*=2;for(i=1;i<=m;i++){if(xt[i].x==1){x1=xt[i].x1^last_ans;y1=xt[i].y1^last_ans;x2=xt[i].x2^last_ans;add(rt,x1,y1,0,x2);if(rt==0)rt=1;if(nt!=0&&tot%nt==0)rt=build(1,tot,0);} else{x1=xt[i].x1^last_ans;y1=xt[i].y1^last_ans;x2=xt[i].x2^last_ans;y2=xt[i].y2^last_ans;last_ans=ask(rt,x1,y1,x2,y2,0);printf("%d\n",last_ans);}//last_ans=0;}return 0;}


0 0
原创粉丝点击