题目描述
四维空间真是美妙。 现在有nnn个四维空间中的点,请求出一条最长的路径,满足任意一维坐标都是单调不降的。 注意路径起点是任意选择的,并且路径与输入顺序无关(路径顺序不一定要满足在输入中是升序)。
题解
- 第一维排序,然后就是个3D-tree
代码
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #define N 50010 6 using namespace std; 7 int n,ans,Ans,D,root,fa[N],pos[N],p[3][4]; 8 struct node 9 { 10 int d[4],id; 11 bool operator < (const node &a) const { return d[D]<a.d[D]; } 12 }a[N]; 13 struct kdtree{int d[3],mn[3],mx[3],ch[2],v,q;}t[N]; 14 bool cmp(node a,node b) { for (int k=3;~k;k--) if (a.d[k]^b.d[k]) return a.d[k]<b.d[k]; return a.id<b.id; } 15 void change(int x,int y) { for (int i=0;i<3;i++) t[x].mn[i]=min(t[x].mn[i],t[y].mn[i]),t[x].mx[i]=max(t[x].mx[i],t[y].mx[i]); } 16 bool pd1(int x) { for (int i=0;i<3;i++) if (t[x].mn[i]<p[0][i]||t[x].mx[i]>p[1][i]) return false; return true; } 17 bool pd2(int x) { for (int i=0;i<3;i++) if (t[x].mn[i]>p[1][i]||t[x].mx[i]<p[0][i]) return true; return false; } 18 bool pd3(int x) { for (int i=0;i<3;i++) if (t[x].d[i]<p[0][i]||t[x].d[i]>p[1][i]) return false; return true; } 19 int build(int d,int l,int r) 20 { 21 int mid=l+r>>1; 22 D=d,nth_element(a+l,a+mid,a+r+1),pos[a[mid].id]=mid; 23 for (int i=0;i<3;i++) t[mid].d[i]=t[mid].mn[i]=t[mid].mx[i]=a[mid].d[i]; 24 if (l<mid) fa[t[mid].ch[0]=build((d+1)%3,l,mid-1)]=mid,change(mid,t[mid].ch[0]); 25 if (r>mid) fa[t[mid].ch[1]=build((d+1)%3,mid+1,r)]=mid,change(mid,t[mid].ch[1]); 26 return mid; 27 } 28 void query(int d) 29 { 30 if (t[d].q<=ans) return; 31 if (pd1(d)) { ans=max(ans,t[d].q); return; } 32 if (pd2(d)) return; 33 if (pd3(d)) ans=max(ans,t[d].v); 34 if (t[d].ch[0]) query(t[d].ch[0]); 35 if (t[d].ch[1]) query(t[d].ch[1]); 36 } 37 int main() 38 { 39 scanf("%d",&n); 40 for (int i=1;i<=n;i++) { for (int j=0;j<4;j++) scanf("%d",&a[i].d[j]); a[i].id=i; } 41 root=build(0,1,n),sort(a+1,a+n+1,cmp); 42 for (int i=1;i<=n;i++) 43 { 44 for (int j=0;j<3;j++) p[0][j]=0,p[1][j]=a[i].d[j]; 45 ans=0,query(root),ans++,Ans=max(Ans,ans),t[pos[a[i].id]].v=ans; 46 for (int p=pos[a[i].id];p;p=fa[p]) t[p].q=max(t[p].q,ans); 47 } 48 printf("%d",Ans); 49 }