bzoj 4066

K-D tree

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 inline int read()
  5 {
  6     int x=0,f=1; char ch=getchar();
  7     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  8     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
  9     return x*f;
 10 }
 11 int n,D;
 12 ll lastans;
 13 struct node
 14 {
 15     int d[2],mx[2],mi[2],val,l,r;
 16     ll sum;
 17 }p[200010];
 18 bool operator == (const node a,const node b)
 19 {
 20     return (a.d[0]==b.d[0])&&(a.d[1]==b.d[1]);
 21 }
 22 bool operator <(const node a,const node b)
 23 {
 24     return a.d[D]<b.d[D];
 25 }
 26 bool in(int x11,int y11,int x21,int y21,int x12,int y12,int x22,int y22)
 27 {
 28     return (x11<=x12)&&(x21>=x22)&&(y11<=y12)&&(y21>=y22);
 29 }
 30 bool out(int x11,int y11,int x21,int y21,int x12,int y12,int x22,int y22)
 31 {
 32     return (x11>x22)||(y11>y22)||(x21<x12)||(y21<y12);
 33 }
 34 struct KDTree
 35 {
 36     node tree[200010],tmp;
 37     int tot,rt;
 38     void updata(node &x)
 39     {
 40         int l=x.l,r=x.r;
 41         for(int i=0;i<2;i++)
 42         {
 43             x.mi[i]=x.mx[i]=x.d[i];
 44             if(l) x.mi[i]=min(x.mi[i],tree[l].mi[i]),
 45                   x.mx[i]=max(x.mx[i],tree[l].mx[i]);
 46             if(r) x.mi[i]=min(x.mi[i],tree[r].mi[i]),
 47                   x.mx[i]=max(x.mx[i],tree[r].mx[i]);
 48         }
 49         x.sum=x.val+tree[l].sum+tree[r].sum;
 50     }
 51     void insert(int D,int &x)
 52     {
 53         if(!x)
 54         {
 55             x=++tot;
 56             tree[x]=tmp; return ;
 57         }
 58         else if(tmp==tree[x])
 59         {
 60             tree[x].val+=tmp.val;
 61             tree[x].sum+=tmp.val;
 62             return ;
 63         }
 64         if(tmp.d[D]<tree[x].d[D]) insert(D^1,tree[x].l);
 65         else insert(D^1,tree[x].r);
 66         updata(tree[x]);
 67     }
 68     ll query(int x1,int y1,int x2,int y2,int x)
 69     {
 70         ll tt=0;
 71         if(in(x1,y1,x2,y2,tree[x].mi[0],tree[x].mi[1],tree[x].mx[0],tree[x].mx[1])) return tree[x].sum;
 72         if(out(x1,y1,x2,y2,tree[x].mi[0],tree[x].mi[1],tree[x].mx[0],tree[x].mx[1])) return 0;
 73         if(in(x1,y1,x2,y2,tree[x].d[0],tree[x].d[1],tree[x].d[0],tree[x].d[1])) tt+=tree[x].val;
 74         tt+=query(x1,y1,x2,y2,tree[x].l)+query(x1,y1,x2,y2,tree[x].r);
 75         return tt;
 76     }
 77     int rebuilt(int l,int r,int f)
 78     {
 79         if(l>r) return 0;
 80         int mid=(l+r)>>1;
 81         D=f;nth_element(p+l,p+mid,p+r+1);
 82         tree[mid]=p[mid];
 83         tree[mid].l=rebuilt(l,mid-1,f^1);
 84         tree[mid].r=rebuilt(mid+1,r,f^1);
 85         updata(tree[mid]);
 86         return mid;
 87     }
 88 }T;
 89 
 90 int main()
 91 {
 92     //freopen("read.in","r",stdin);
 93     n=read();int m=10000;
 94     while(1)
 95     {
 96         int com=read();
 97         if(com==3) return 0;
 98         if(com==1)
 99         {
100             int x=read()^lastans,y=read()^lastans,A=read()^lastans;
101             T.tmp.d[0]=x;T.tmp.d[1]=y; 
102             T.tmp.sum=T.tmp.val=A;
103             T.tmp.mi[0]=T.tmp.mx[0]=x;
104             T.tmp.mi[1]=T.tmp.mx[1]=y;
105             T.insert(0,T.rt);
106             if(T.tot==m)
107             {
108                 for(int i=1;i<=T.tot;i++) p[i]=T.tree[i];
109                 T.rt=T.rebuilt(1,T.tot,0);m+=10000;
110             }
111         }
112         if(com==2)
113         {
114             int x1=read()^lastans,y1=read()^lastans,
115                 x2=read()^lastans,y2=read()^lastans;
116             if(x1>x2) swap(x1,x2); if(y1>y2) swap(y1,y2);
117             lastans=T.query(x1,y1,x2,y2,T.rt);
118             printf("%lld\n",lastans);
119         }
120     }
121     return 0;
122 }

 

posted @ 2017-02-12 20:37  蛤鸡  阅读(118)  评论(0编辑  收藏  举报