四维偏序(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 }
View Code

 

以上是关于四维偏序(K-D-Tree+rebuild)的主要内容,如果未能解决你的问题,请参考以下文章

教程CDQ套CDQ——四维偏序问题转载

COGS2479(四维偏序)

HDU 5126 stars (四维偏序+树状数组)

COGS 2479. [HZOI 2016]偏序 [CDQ分治套CDQ分治 四维偏序]

论如何优雅的用bitset来求四维偏序

四维偏序