K-D树学习笔记

这东西其实就是高维二叉树?(反正我只会二维的)

大概就是把一个高维矩形按每一维分,一个点(及其子树)就表示一个高维区间,乱搞一下,就……没了?

  1 //BZOJ4066 "简单"题
  2 //维护N*N矩形,初始全为0,支持两种操作:
  3 //1.将格子(x,y)的数字加上A
  4 //2.求(x1,y1)到(x2,y2)这个矩形内的数字和
  5 //3.结束程序
  6 //由于平衡性,每5000次插入就暴力重构一次 
  7 #include<algorithm>
  8 #include<iostream>
  9 #include<cstring>
 10 #include<cstdio>
 11 #include<cmath>
 12 using namespace std;
 13 int D;
 14 struct kdnode{
 15     int ls,rs,num,v,d[2],mi[2],mx[2];
 16     int &operator [](int x){
 17         return d[x];
 18     }
 19     friend bool operator <(kdnode a,kdnode b){
 20         return a[D]<b[D];
 21     }
 22 }t[200001],rb[200001],s;
 23 int n,op,x1,yy,x2,y2,v,rt=0,tot=0,R=5000,ans=0;
 24 bool inside(int x1,int yy,int x2,int y2,int x3,int y3,int x4,int y4){
 25     return x1<=x3&&x2>=x4&&yy<=y3&&y2>=y4;
 26 }
 27 bool outside(int x1,int yy,int x2,int y2,int x3,int y3,int x4,int y4){
 28     return x1>x4||x2<x3||yy>y4||y2<y3;
 29 }
 30 void pushup(int u){
 31     int l=t[u].ls,r=t[u].rs;
 32     for(int i=0;i<=1;i++){
 33         t[u].mi[i]=t[u].mx[i]=t[u][i];
 34         if(l)t[u].mi[i]=min(t[u].mi[i],t[l].mi[i]);
 35         if(l)t[u].mx[i]=max(t[u].mx[i],t[l].mx[i]);
 36         if(r)t[u].mi[i]=min(t[u].mi[i],t[r].mi[i]);
 37         if(r)t[u].mx[i]=max(t[u].mx[i],t[r].mx[i]);
 38     }
 39     t[u].num=t[l].num+t[r].num+t[u].v;
 40 }
 41 int query(int u,int x1,int yy,int x2,int y2){
 42     int ret=0;
 43     if(!u)return 0;
 44     if(inside(x1,yy,x2,y2,t[u].mi[0],t[u].mi[1],t[u].mx[0],t[u].mx[1]))return t[u].num;
 45     if(outside(x1,yy,x2,y2,t[u].mi[0],t[u].mi[1],t[u].mx[0],t[u].mx[1]))return 0;
 46     if(inside(x1,yy,x2,y2,t[u][0],t[u][1],t[u][0],t[u][1]))ret+=t[u].v;
 47     ret+=query(t[u].ls,x1,yy,x2,y2)+query(t[u].rs,x1,yy,x2,y2);
 48     return ret;
 49 }
 50 void ins(int &u,bool d){
 51     if(!u){
 52         u=++tot;
 53         t[u][0]=t[u].mi[0]=t[u].mx[0]=s[0];
 54         t[u][1]=t[u].mi[1]=t[u].mx[1]=s[1];
 55     }
 56     if(s[0]==t[u][0]&&s[1]==t[u][1]){
 57         t[u].v+=s.v;
 58         t[u].num+=s.v;
 59         return; 
 60     }
 61     if(s[d]<t[u][d])ins(t[u].ls,d^1);
 62     else ins(t[u].rs,d^1);
 63     pushup(u);
 64 }
 65 int rebuild(int l,int r,bool d){
 66     if(l>r)return 0;
 67     int mid=(l+r)/2;
 68     D=d;
 69     nth_element(rb+l,rb+mid,rb+r+1);
 70     t[mid]=rb[mid];
 71     t[mid].ls=rebuild(l,mid-1,d^1);
 72     t[mid].rs=rebuild(mid+1,r,d^1);
 73     pushup(mid);
 74     return mid;
 75 }
 76 int main(){
 77     scanf("%d",&n);
 78     for(;;){
 79         scanf("%d",&op);
 80         if(op==1){
 81             scanf("%d%d%d",&x1,&yy,&v);
 82             x1^=ans;
 83             yy^=ans;
 84             v^=ans;
 85             s[0]=x1;
 86             s[1]=yy;
 87             s.num=s.v=v;
 88             ins(rt,0);
 89             if(tot==R){
 90                 for(int j=1;j<=tot;j++){
 91                     rb[j]=t[j];
 92                 }
 93                 rt=rebuild(1,tot,0);
 94                 R+=5000;
 95             }
 96         }else if(op==2){
 97             scanf("%d%d%d%d",&x1,&yy,&x2,&y2);
 98             x1^=ans;
 99             yy^=ans;
100             x2^=ans;
101             y2^=ans;
102             printf("%d
",(ans=query(rt,x1,yy,x2,y2)));
103         }else break;
104     }
105     return 0;
106 } 
原文地址:https://www.cnblogs.com/dcdcbigbig/p/9224951.html