bzoj4066
分别按照x,y排序
#include<cstdio> #include<algorithm> #include<cctype> using namespace std; struct data{int d[2],l,r,mn[2],mx[2],sum,val;}tr[200005]; int cmpd,ans=0,x1,x2,y1,y2,rt; void read(int &x){ char ch=getchar();x=0;int f=1; while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} x*=f; } int cmp(const data &a,const data &b){ return(a.d[cmpd]<b.d[cmpd]||(a.d[cmpd]==b.d[cmpd]&&a.d[!cmpd]<b.d[!cmpd])); } void updata(int now){ int ls=tr[now].l,rs=tr[now].r; if(ls){ tr[now].mn[0]=min(tr[now].mn[0],tr[ls].mn[0]); tr[now].mn[1]=min(tr[now].mn[1],tr[ls].mn[1]); tr[now].mx[0]=max(tr[now].mx[0],tr[ls].mx[0]); tr[now].mx[1]=max(tr[now].mx[1],tr[ls].mx[1]); } if(rs){ tr[now].mn[0]=min(tr[now].mn[0],tr[rs].mn[0]); tr[now].mn[1]=min(tr[now].mn[1],tr[rs].mn[1]); tr[now].mx[0]=max(tr[now].mx[0],tr[rs].mx[0]); tr[now].mx[1]=max(tr[now].mx[1],tr[rs].mx[1]); } tr[now].sum=tr[ls].sum+tr[rs].sum+tr[now].val; } bool ok(int now){ return (tr[now].d[0]>=x1 && tr[now].d[1]>=y1 && tr[now].d[0]<=x2 && tr[now].d[1]<=y2); } int check(int now){ if(tr[now].mn[0]>=x1 && tr[now].mn[1]>=y1 && tr[now].mx[0]<=x2 && tr[now].mx[1]<=y2)return 1; if(tr[now].mn[0]>x2 || tr[now].mn[1]>y2 || tr[now].mx[0]<x1 || tr[now].mx[1]<y1)return -1; return 0; } void query(int now){ if(ok(now))ans+=tr[now].val; if(tr[now].l){ int vis=check(tr[now].l); if(vis==1)ans+=tr[tr[now].l].sum;else if(vis==0)query(tr[now].l); } if(tr[now].r){ int vis=check(tr[now].r); if(vis==1)ans+=tr[tr[now].r].sum;else if(vis==0)query(tr[now].r); } } int rebuild(int l,int r,int flag){ cmpd=flag; int mid=(l+r)>>1; nth_element(tr+l+1,tr+mid+1,tr+r+1,cmp); tr[mid].mn[0]=tr[mid].mx[0]=tr[mid].d[0]; tr[mid].mn[1]=tr[mid].mx[1]=tr[mid].d[1]; tr[mid].sum=tr[mid].val; tr[mid].l=tr[mid].r=0; if(l!=mid)tr[mid].l=rebuild(l,mid-1,!flag); if(r!=mid)tr[mid].r=rebuild(mid+1,r,!flag); updata(mid); return mid; } void insert(int now){ if(!rt){rt=now;return;} int p=rt,flag=0; while(1){ if(tr[now].mn[0]<tr[p].mn[0])tr[p].mn[0]=tr[now].mn[0]; if(tr[now].mn[1]<tr[p].mn[1])tr[p].mn[1]=tr[now].mn[1]; if(tr[now].mx[0]>tr[p].mx[0])tr[p].mx[0]=tr[now].mx[0]; if(tr[now].mx[1]>tr[p].mx[1])tr[p].mx[1]=tr[now].mx[1]; tr[p].sum+=tr[now].sum; if(tr[now].d[flag]<=tr[p].d[flag]){ if(!tr[p].l){tr[p].l=now;break;} else p=tr[p].l; }else{ if(!tr[p].r){tr[p].r=now;break;} else p=tr[p].r; } flag=!flag; } } int main(){ int cnt,typ,x,y,v; read(cnt);cnt=0; while(scanf("%d",&typ)){ if(typ==3)break; if(typ==1){ read(x);read(y);read(v); x^=ans;y^=ans;v^=ans; cnt++; tr[cnt].mn[0]=tr[cnt].mx[0]=tr[cnt].d[0]=x; tr[cnt].mn[1]=tr[cnt].mx[1]=tr[cnt].d[1]=y; tr[cnt].val=tr[cnt].sum=v; insert(cnt); if(cnt%10000==0)rt=rebuild(1,cnt,0); } if(typ==2){ read(x1);read(y1);read(x2);read(y2); x1^=ans;y1^=ans;x2^=ans;y2^=ans; ans=0; query(rt); printf("%d\n",ans); } } }