您的位置:首页 > 其它

[bzoj4066]简单题

2016-04-23 10:24 417 查看

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
,p
,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);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: