多维维护问题,每层换一维进行统计。
bzoj4066 简单题
题目大意:给(x,y)+A,求(x1,y1)~(x2,y2)的权值和。
思路:kd-tree,但这道题目中重建是特判的。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define N 200005 using namespace std; inline int in(){ char ch=getchar();int x=0; while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9'){ x=x*10+ch-'0';ch=getchar(); }return x;} int dd,rt,tt=0; struct use{ int d[2],mn[2],mx[2],sm,v,l,r; int &operator[](int x){return d[x];} bool operator==(const use&x)const{return d[0]==x.d[0]&&d[1]==x.d[1];} bool operator<(const use &x)const{return d[dd]<x.d[dd];} }tr[N],nt,ci[N]; inline bool bin(int x1,int y1,int x2,int y2,int a1,int b1,int a2,int b2){ return x1<=a1&&y1<=b1&&x2>=a2&&y2>=b2; } inline bool bout(int x1,int y1,int x2,int y2,int a1,int b1,int a2,int b2){ return x1>a2||x2<a1||y1>b2||y2<b1; } void updata(int x){ int i,l,r;l=tr[x].l;r=tr[x].r; for (i=0;i<2;++i){ tr[x].mn[i]=tr[x].mx[i]=tr[x][i]; if (l){ tr[x].mn[i]=min(tr[x].mn[i],tr[l].mn[i]); tr[x].mx[i]=max(tr[x].mx[i],tr[l].mx[i]); }if (r){ tr[x].mn[i]=min(tr[x].mn[i],tr[r].mn[i]); tr[x].mx[i]=max(tr[x].mx[i],tr[r].mx[i]); } }tr[x].sm=tr[x].v+tr[l].sm+tr[r].sm;} void ins(int &x,int d){ if (!x){x=++tt;tr[x]=nt;return;} if (tr[x]==nt){tr[x].v+=nt.v;tr[x].sm+=nt.v;return;} if (nt[d]<tr[x][d]) ins(tr[x].l,d^1); else ins(tr[x].r,d^1); updata(x); } int query(int x,int d,int x1,int y1,int x2,int y2){ if (!x) return 0; if (bin(x1,y1,x2,y2,tr[x].mn[0],tr[x].mn[1],tr[x].mx[0],tr[x].mx[1])) return tr[x].sm; if (bout(x1,y1,x2,y2,tr[x].mn[0],tr[x].mn[1],tr[x].mx[0],tr[x].mx[1])) return 0; int sm=0; if (bin(x1,y1,x2,y2,tr[x][0],tr[x][1],tr[x][0],tr[x][1])) sm+=tr[x].v; sm+=query(tr[x].l,d^1,x1,y1,x2,y2)+query(tr[x].r,d^1,x1,y1,x2,y2); return sm;} int rebuild(int l,int r,int d){ if (l>r) return 0; int mid=(l+r)>>1; dd=d;nth_element(ci+l,ci+mid,ci+r+1); tr[mid]=ci[mid]; tr[mid].l=rebuild(l,mid-1,d^1); tr[mid].r=rebuild(mid+1,r,d^1); updata(mid);return mid;} int main(){ int op,x1,y1,x2,y2,v,i,la=0,m=10000; op=in();tr[0]=(use){0,0,0,0,0,0,0,0,0,0}; while((op=in())!=3){ if (op==1){ x1=in()^la;y1=in()^la;v=in()^la; nt=(use){x1,y1,x1,y1,x1,y1,v,v,0,0}; ins(rt,0); if (tt==m){ for (i=1;i<=tt;++i) ci[i]=tr[i]; rt=rebuild(1,tt,0);m+=10000; } }else{ x1=in()^la;y1=in()^la;x2=in()^la;y2=in()^la; la=query(rt,0,x1,y1,x2,y2); printf("%d\n",la); } } }