4066: 简单题
Time Limit: 50 Sec Memory Limit: 20 MB
Submit: 1563 Solved: 420
[Submit][Status][Discuss]
Description
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范围内并且解码之后数据仍合法。
KD树模板题。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=200010;
int n,ans,siz,root,o,D;
struct S{
int v,sum,d[2],minn[2],maxn[2],l,r;
int &operator [](int x){
return d[x];
}
bool operator == (const S &x)const{
return x.d[0]==d[0]&&x.d[1]==d[1];
}
bool operator < (const S &x)const{
return d[D]<x.d[D];
}
}tr[N],p[N],now;
inline int IN(){
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;
}
inline void update(int k){
int l=tr[k].l,r=tr[k].r,i;
tr[k].sum=tr[k].v+tr[l].sum+tr[r].sum;
for(i=0;i<=1;++i){
tr[k].minn[i]=tr[k].maxn[i]=tr[k][i];
if(l){
tr[k].minn[i]=min(tr[k].minn[i],tr[l].minn[i]);
tr[k].maxn[i]=max(tr[k].maxn[i],tr[l].maxn[i]);
}
if(r){
tr[k].minn[i]=min(tr[k].minn[i],tr[r].minn[i]);
tr[k].maxn[i]=max(tr[k].maxn[i],tr[r].maxn[i]);
}
}
}
inline void insert(int &k,int flag){
if(!k){
k=++siz;
tr[k][0]=tr[k].minn[0]=tr[k].maxn[0]=now[0];
tr[k][1]=tr[k].minn[1]=tr[k].maxn[1]=now[1];
}
if(now==tr[k]){
tr[k].sum+=now.sum;
tr[k].v+=now.v;
return ;
}
if(now[flag]<tr[k][flag]) insert(tr[k].l,flag^1);
else insert(tr[k].r,flag^1);
update(k);
}
#define mid (l+r)/2
inline int rebuild(int l,int r,int flag){
if(l>r) return 0;
D=flag;nth_element(p+l,p+mid,p+r+1);
tr[mid]=p[mid];
tr[mid].l=rebuild(l,mid-1,flag^1);
tr[mid].r=rebuild(mid+1,r,flag^1);
update(mid);
return mid;
}
inline bool in(int x1,int y1,int x2,int y2,int X1,int Y1,int X2,int Y2){
return x1<=X1&&x2>=X2&&y1<=Y1&&y2>=Y2;
}
inline bool out(int x1,int y1,int x2,int y2,int X1,int Y1,int X2,int Y2){
return x1>X2||x2<X1||y1>Y2||y2<Y1;
}
inline int query(int k,int x,int y,int xx,int yy){
if(!k) return 0;
int sum=0;
if(in(x,y,xx,yy,tr[k].minn[0],tr[k].minn[1],tr[k].maxn[0],tr[k].maxn[1])) return tr[k].sum;
if(out(x,y,xx,yy,tr[k].minn[0],tr[k].minn[1],tr[k].maxn[0],tr[k].maxn[1])) return 0;
if(in(x,y,xx,yy,tr[k][0],tr[k][1],tr[k][0],tr[k][1])) sum+=tr[k].v;
return sum+query(tr[k].l,x,y,xx,yy)+query(tr[k].r,x,y,xx,yy);
}
int main(){
int i,t,x,y,xx,yy,z;
n=IN();
o=10000;
while(1){
t=IN();
if(t==3) break;
x=IN();y=IN();
x^=ans;y^=ans;
if(t==1){
z=IN();z^=ans;
now[0]=x;now[1]=y;
now.v=now.sum=z;
insert(root,0);
if(siz==o){
for(i=1;i<=siz;++i) p[i]=tr[i];
root=rebuild(1,siz,0);
o+=10000;
}
}
if(t==2){
xx=IN();yy=IN();
xx^=ans;yy^=ans;
ans=query(root,x,y,xx,yy);
printf("%d\n",ans);
}
}
}