zoukankan      html  css  js  c++  java
  • [KD-tree] Luogu P3769 TATT

    题目描述

    四维空间真是美妙。 现在有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 }
  • 相关阅读:
    PHP多维数组转为一维数组的方法实例
    PHP内存模拟分析
    linux windows mysql安装
    Ubuntu 连接Xshell 不能连接
    Linux软链挂载
    python 数据库连接 CRUD
    RabbitMQ 实现广播订阅
    Redis 实现广播订阅
    python-切片
    python中的3目运算(3元表达式)
  • 原文地址:https://www.cnblogs.com/Comfortable/p/11312901.html
Copyright © 2011-2022 走看看