KD树

BZOJ4066

板子:

  1 #include <bits/stdc++.h>
  2 #define LL long long 
  3 using namespace std;
  4 int n,op,x,y,z,M,a1,a2,b1,b2; LL ans;
  5 int read(){
  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 namespace KD{
 12     int cnt,rt,D;
 13     struct P{
 14         int d[2],p[2],q[2],v,l,r; LL s;
 15         int &operator[](int x) {return d[x];}
 16     }a[200005],b[200005],A;
 17     bool operator==(P a,P b){
 18         return a[0]==b[0]&&a[1]==b[1];
 19     }
 20     bool operator<(P a,P b){
 21         return a[D]<b[D];
 22     }
 23       
 24     void up(int u){
 25         int l=a[u].l,r=a[u].r;
 26         a[u].s=a[l].s+a[r].s+a[u].v;
 27         for (int i=0;i<2;++i){
 28             a[u].p[i]=a[u].q[i]=a[u][i];
 29             if (l) a[u].p[i]=min(a[u].p[i],a[l].p[i]);
 30             if (l) a[u].q[i]=max(a[u].q[i],a[l].q[i]);
 31             if (r) a[u].p[i]=min(a[u].p[i],a[r].p[i]);
 32             if (r) a[u].q[i]=max(a[u].q[i],a[r].q[i]);
 33         }
 34     }
 35     void add(int &u,bool F){
 36         if (!u){
 37             u=++cnt;
 38             a[u][0]=a[u].p[0]=a[u].q[0]=A[0];
 39             a[u][1]=a[u].p[1]=a[u].q[1]=A[1];
 40         }
 41         if (A==a[u]){
 42             a[u].v+=A.v; a[u].s+=A.v;
 43             return;
 44         }
 45         if (A[F]<a[u][F]) add(a[u].l,F^1);
 46             else add(a[u].r,F^1);
 47         up(u);
 48     }    
 49     int go(int l,int r,bool F){
 50         if (l>r) return 0;
 51         int m=l+r>>1; D=F;
 52         nth_element(b+l,b+m,b+r+1);
 53         a[m]=b[m];
 54         a[m].l=go(l,m-1,F^1);
 55         a[m].r=go(m+1,r,F^1);
 56         up(m);
 57         return m;
 58     }
 59     bool in(P a,P b){
 60         return a.p[0]>=b.p[0]&&a.p[1]>=b.p[1]&&a.q[0]<=b.q[0]&&a.q[1]<=b.q[1];
 61     }
 62     bool out(P a,P b){
 63         return a.q[0]<b.p[0]||a.q[1]<b.p[1]||a.p[0]>b.q[0]||a.p[1]>b.q[1];
 64     }
 65     LL sum(int u){
 66         if (!u||out(a[u],A)) return 0;
 67         if (in(a[u],A)) return a[u].s;
 68         LL tmp=0;
 69         if (a[u][0]>=A.p[0]&&a[u][0]<=A.q[0]&&a[u][1]>=A.p[1]&&a[u][1]<=A.q[1]) tmp=a[u].v;
 70         tmp+=sum(a[u].l)+sum(a[u].r);
 71         return tmp;
 72     }
 73      
 74     void insert(int x,int y,int z){
 75         A[0]=A.p[0]=A.q[0]=x;
 76         A[1]=A.p[1]=A.q[1]=y;
 77         A.s=A.v=z; add(rt,0);
 78     }
 79     void rebuild(){
 80         for (int i=1;i<=cnt;++i) b[i]=a[i];
 81         rt=go(1,cnt,0);
 82     }
 83     LL qsum(int a1,int b1,int a2,int b2){
 84         A.p[0]=a1; A.q[0]=a2;
 85         A.p[1]=b1; A.q[1]=b2;
 86         return sum(rt);
 87     }
 88 }
 89 int main(){
 90     n=read(); M=10000;
 91     while (1){
 92         op=read();
 93         if (op==3) return 0;
 94         if (op==1){
 95             x=read(); y=read(); z=read();
 96             KD::insert(x^ans,y^ans,z^ans);
 97             if (KD::cnt==M)
 98                 KD::rebuild(),M+=10000;
 99         }else{
100             a1=read()^ans; b1=read()^ans; a2=read()^ans; b2=read()^ans;
101             printf("%lld\n",ans=KD::qsum(a1,b1,a2,b2));
102         }
103     }
104     return 0;
105 }
Fading

 

posted @ 2017-11-14 16:16  cyz666  阅读(133)  评论(0编辑  收藏