四维偏序(K-D-Tree+rebuild)
Posted zcysky
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了四维偏序(K-D-Tree+rebuild)相关的知识,希望对你有一定的参考价值。
其实只是放个代码,会K-D-Tree的同学看了就知道怎么rebuild了,其实也是很简单粗暴的……
单独再发一次吧,感觉把代码跟之前的一起发不知道啥时候就找不到了……
1 #include<bits/stdc++.h> 2 #define N 50010 3 #define inf 1000000009 4 #define lson (t1[o].l) 5 #define rson (t1[o].r) 6 using namespace std; 7 typedef long long ll; 8 int n,m,q[N],rt,dis,top=0;int tot=0,F; 9 inline int read(){ 10 int f=1,x=0;char ch; 11 do{ch=getchar();if(ch==‘-‘)f=-1;}while(ch<‘0‘||ch>‘9‘); 12 do{x=x*10+ch-‘0‘;ch=getchar();}while(ch>=‘0‘&&ch<=‘9‘); 13 return f*x; 14 }int ans=0; 15 struct Point{ 16 int d[4],maxv[4],minv[4],l,r,f,size,v,ma; 17 inline int& operator [] (int x){return d[x];} 18 inline int in(){for(int i=0;i<4;i++)d[i]=read();} 19 }t1[N],t2[N],it; 20 bool cmp(int a,int b){return t1[a][F]<t2[b][F];} 21 bool operator < (Point a,Point b){ 22 for(int i=0;i<=3;i++){ 23 if(a.d[i]<b.d[i])return 1; 24 if(a.d[i]>b.d[i])return 0; 25 } 26 return 0; 27 } 28 inline void pushup(int o){ 29 for(int i=0;i<=3;i++){ 30 t1[o].minv[i]=min(t1[o].d[i],min(t1[lson].minv[i],t1[rson].minv[i])); 31 t1[o].maxv[i]=max(t1[o].d[i],max(t1[lson].maxv[i],t1[rson].maxv[i])); 32 } 33 t1[o].ma=max(t1[o].v,max(t1[lson].ma,t1[rson].ma)); 34 t1[o].size=t1[lson].size+t1[rson].size+1; 35 } 36 int build(int l,int r,int f){ 37 int mid=(l+r)>>1;F=f; 38 nth_element(q+l,q+mid,q+r+1,cmp); 39 int o=q[mid];t1[o].f=f;lson=0;rson=0; 40 if(l<mid)lson=build(l,mid-1,(f+1)%4); 41 if(r>mid)rson=build(mid+1,r,(f+1)%4); 42 pushup(o);return o; 43 } 44 void dfs(int o){ 45 if(!o)return;q[++top]=o; 46 dfs(lson);dfs(rson); 47 } 48 void rebuild(int &o){ 49 top=0;dfs(o); 50 o=build(1,top,t1[o].f); 51 } 52 inline int newnode(int f){ 53 int o=++tot;t1[tot].f=f;t1[o]=it; 54 for(int i=0;i<=3;i++)t1[o].minv[i]=t1[o].maxv[i]=t1[o][i]; 55 t1[o].ma=t1[o].v;t1[o].size=1; 56 return o; 57 } 58 void ins(int &o,int f){ 59 if(!o){o=newnode(f);return;} 60 if(t1[o][f]<it[f]){ 61 ins(lson,(f+1)%4); 62 pushup(o); 63 if(t1[lson].size>t1[o].size*0.75)rebuild(o); 64 } 65 else{ 66 ins(rson,(f+1)%4); 67 pushup(o); 68 if(t1[rson].size>t1[o].size*0.75)rebuild(o); 69 } 70 } 71 inline int check(int o){ 72 if(!o)return 0;int _=0; 73 for(int i=0;i<=3;i++)if(t1[o].maxv[i]<=it.d[i])_++; 74 if(_==4)return _; 75 _=1; 76 for(int i=0;i<=3;i++)if(t1[o].minv[i]>it[i])_=0; 77 return _; 78 } 79 inline int calcdis(Point x,Point y){ 80 for(int i=0;i<=3;i++)if(x[i]>y[i])return 0; 81 return x.v; 82 } 83 void query(int o){ 84 ans=max(calcdis(t1[o],it),ans); 85 int dl=check(lson),dr=check(rson); 86 if(dl==4)ans=max(ans,t1[lson].ma); 87 else if(dl&&ans<t1[lson].ma)query(lson); 88 if(dr==4)ans=max(ans,t1[rson].ma); 89 else if(dr&&ans<t1[rson].ma)query(rson); 90 } 91 int main(){ 92 n=read(); 93 for(int i=0;i<=3;i++)t1[0].minv[i]=inf,t1[0].maxv[i]=-inf; 94 t1[0].ma=-inf; 95 for(int i=1;i<=n;i++){ 96 t2[i].in();t2[i].v=1; 97 } 98 sort(t2+1,t2+n+1); 99 int _=0; 100 for(int i=1;i<=n;i++){ 101 ans=0;it=t2[i]; 102 query(rt); 103 t2[i].v+=ans;it=t2[i]; 104 _=max(_,t2[i].v);ins(rt,0); 105 } 106 printf("%d\n",_); 107 }
以上是关于四维偏序(K-D-Tree+rebuild)的主要内容,如果未能解决你的问题,请参考以下文章