rt,按照题解区奆佬的做法,将静态四维偏序转为动态三维偏序,再用 k-d tree 优化 dp,时间复杂度 Θ(n35)。
RE on #2。
代码应该还算清晰,就不写注释了。
#include<bits/stdc++.h>
using namespace std;
const int N=5e4+5;
const int inf=1e9;
int cmptype=-1;
struct Point{
int id,x0;
vector<int>x;
friend bool operator<(Point A,Point B){
if(~cmptype){
return A.x[cmptype]<B.x[cmptype];
}
if(A.x0!=B.x0){
return A.x0<B.x0;
}
for(int i=0;i<3;i++){
if(A.x[i]!=B.x[i]){
return A.x[i]<B.x[i];
}
}
return 1;
}
}a[N];
int p[N],p2[N],idx;
struct node{
int ch[2];
int par;
vector<int>l,r,x;
int val,maxn;
}tr[N];
int ans;
struct KDTree{
#define lc tr[i].ch[0]
#define rc tr[i].ch[1]
#define mid (l+r)/2
void build(int &i,int l,int r,vector<int>L,vector<int>R,int type){
if(l>r){
return;
}
i=++idx;
cmptype=type;
nth_element(a+l,a+mid,a+r+1);
vector<int>L1=L,L2=L,R1=R,R2=R;
R1[type]=a[mid].x[type],L2[type]=a[mid].x[type];
build(lc,l,mid-1,L1,R1,(type+1)%3);tr[lc].par=i;
build(rc,mid+1,r,L2,R2,(type+1)%3);tr[rc].par=i;
tr[i].l=L,tr[i].r=R,tr[i].x=a[mid].x;
p[mid]=i;
}
void query(int i,vector<int>L,vector<int>R){
if(!i){
return;
}
if(tr[i].maxn<=ans){
return;
}
auto check=[&](){
for(register int d=0;d<3;d++){
if(L[d]>tr[i].l[d]){
return 0;
}
if(R[d]<tr[i].r[d]){
return 0;
}
}
return 1;
};
if(check()){
ans=tr[i].maxn;
return;
}
auto check2=[&](){
for(register int d=0;d<3;d++){
if(R[d]<tr[i].l[d]){
return 0;
}
if(L[d]>tr[i].r[d]){
return 0;
}
}
return 1;
};
if(!check2()){
return;
}
auto check3=[&](){
for(register int d=0;d<3;d++){
if(L[d]>tr[i].x[d]){
return 0;
}
if(R[d]<tr[i].x[d]){
return 0;
}
}
return 1;
};
if(check3()){
ans=max(ans,tr[i].val);
}
query(lc,L,R);
query(rc,L,R);
}
void update(int i,int val){
tr[i].val=max(tr[i].val,val);
while(i){
tr[i].maxn=max(tr[i].maxn,val);
i=tr[i].par;
}
}
#undef lc
#undef rc
#undef mid
}kdt;
int n,rt,f[N];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
vector<int>x(3);
scanf("%d",&a[i].x0);
for(int j=0;j<3;j++){
scanf("%d",&x[j]);
}
a[i].x=x;
}
sort(a+1,a+n+1);
for(int i=1;i<=n;i++){
a[i].id=i;
}
kdt.build(rt,1,n,vector<int>(3,-inf),vector<int>(3,inf),0);
for(int i=1;i<=n;i++){
p2[a[i].id]=i;
}
int res=0;
for(int i=1;i<=n;i++){
ans=0;
kdt.query(rt,vector<int>(3,-inf),a[p2[i]].x);
f[i]=ans+1;
res=max(res,f[i]);
kdt.update(p[p2[i]],f[i]);
}
printf("%d\n",res);
return 0;
}