P4148 簡單題(KDTree)
阿新 • • 發佈:2018-12-09
KDTree
修改權值當做插入節點,不平衡就暴力重構,詢問的時候判斷當前節點代表的矩形是否在詢問的矩形的,是的話返回答案,相離返回0,否則的話判斷當前點是否在矩形內,然後繼續遞迴下去
//minamoto #include<bits/stdc++.h> #define R register #define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i) #define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i) #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v) template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;} template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;} using namespace std; char buf[1<<21],*p1=buf,*p2=buf; inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;} int read(){ R int res,f=1;R char ch; while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1); for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0'); return res*f; } char sr[1<<21],z[20];int C=-1,Z=0; inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;} void print(R int x){ if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x; while(z[++Z]=x%10+48,x/=10); while(sr[++C]=z[Z],--Z);sr[++C]='\n'; } const int N=2e5+5; struct point{int v[2],w;}pool[N]; struct node{int mn[2],mx[2],sum,l,r,sz;point tp;}tr[N]; int n,m,K,rt,top,cnt,st[N],ans; inline bool operator <(const point &a,const point &b){return a.v[K]<b.v[K];} inline int newnode(){return top?st[top--]:++cnt;} void upd(int p){ int l=tr[p].l,r=tr[p].r; fp(i,0,1){ tr[p].mn[i]=tr[p].mx[i]=tr[p].tp.v[i]; if(l)cmin(tr[p].mn[i],tr[l].mn[i]),cmax(tr[p].mx[i],tr[l].mx[i]); if(r)cmin(tr[p].mn[i],tr[r].mn[i]),cmax(tr[p].mx[i],tr[r].mx[i]); }tr[p].sum=tr[l].sum+tr[r].sum+tr[p].tp.w,tr[p].sz=tr[l].sz+tr[r].sz+1; } int build(int l,int r,int k){ if(l>r)return 0;int mid=(l+r)>>1,p=newnode(); K=k,nth_element(pool+l,pool+mid,pool+r+1),tr[p].tp=pool[mid]; tr[p].l=build(l,mid-1,k^1),tr[p].r=build(mid+1,r,k^1); upd(p);return p; } void pia(int p,int sum){ if(tr[p].l)pia(tr[p].l,sum); pool[sum+tr[tr[p].l].sz+1]=tr[p].tp,st[++top]=p; if(tr[p].r)pia(tr[p].r,sum+tr[tr[p].l].sz+1); } void ck(int &p,int k){ if(tr[p].sz*0.75<tr[tr[p].l].sz||tr[p].sz*0.75<tr[tr[p].r].sz) pia(p,0),p=build(1,tr[p].sz,k); } void ins(int &p,point res,int k){ if(!p)return (void)(p=newnode(),tr[p].l=tr[p].r=0,tr[p].tp=res,upd(p)); res.v[k]<=tr[p].tp.v[k]?ins(tr[p].l,res,k^1):ins(tr[p].r,res,k^1); upd(p),ck(p,k); } inline bool in(int x1,int y1,int x2,int y2,int X1,int Y1,int X2,int Y2){ return x1<=X1&&y1<=Y1&&x2>=X2&&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; } int query(int p,int x1,int y1,int x2,int y2){ if(!p)return 0;int res=0; if(in(x1,y1,x2,y2,tr[p].mn[0],tr[p].mn[1],tr[p].mx[0],tr[p].mx[1]))return tr[p].sum; if(out(x1,y1,x2,y2,tr[p].mn[0],tr[p].mn[1],tr[p].mx[0],tr[p].mx[1]))return 0; if(in(x1,y1,x2,y2,tr[p].tp.v[0],tr[p].tp.v[1],tr[p].tp.v[0],tr[p].tp.v[1]))res+=tr[p].tp.w; res+=query(tr[p].l,x1,y1,x2,y2)+query(tr[p].r,x1,y1,x2,y2);return res; } int main(){ // freopen("testdata.in","r",stdin); n=read();int op,x1,y1,x2,y2; while(true){ op=read();if(op==3)break; if(op==1)ins(rt,(point){read()^ans,read()^ans,read()^ans},0); else{ x1=read()^ans,y1=read()^ans,x2=read()^ans,y2=read()^ans; ans=query(rt,x1,y1,x2,y2),print(ans); } }return Ot(),0; }