分析

可以考虑到 结尾的最长的序列。那么 。所以其实这个是个四维偏序。所以我们考虑 来做。时间复杂度为 。但是有几个非常重要的减枝条件。可以参照代码。

代码

#include<bits/stdc++.h>
using namespace std;
int read() {
    int x = 0,f = 0;char ch = getchar();
    while(!isdigit(ch)) {if(ch == '-')f=1;ch = getchar();}
    while(isdigit(ch)) {x = x*10+ch-'0';ch=getchar();}
    return f?-x:x;
}
const int N = 5e4 + 1000;
struct Node{int s[4],val;
}A[N];
bool cmp(Node a,Node rhs){
    return a.s[0] < rhs.s[0] || (a.s[0] == rhs.s[0] && (a.s[1] < rhs.s[1] || (a.s[1] == rhs.s[1] && (a.s[2] < rhs.s[2] || (a.s[2] == rhs.s[2] && a.s[3] < rhs.s[3])))));
}
struct Tree{int mx[4],mi[4],ch[2],Max;Node p;}t[N];
int n,size,ans,Ans,rt,tot;
void pushup(int u) {
    int lc = t[u].ch[0],rc = t[u].ch[1];
    t[u].Max = t[u].p.val;
    for(int i = 0;i < 4;i++) {
        t[u].mi[i] = t[u].mx[i] = t[u].p.s[i];
        if(lc) t[u].mx[i] = max(t[u].mx[i],t[lc].mx[i]);
        if(rc) t[u].mx[i] = max(t[u].mx[i],t[rc].mx[i]);
        if(lc) t[u].mi[i] = min(t[u].mi[i],t[lc].mi[i]);
        if(rc) t[u].mi[i] = min(t[u].mi[i],t[rc].mi[i]);
    }
    if(lc) t[u].Max = max(t[u].Max,t[lc].Max);
    if(rc) t[u].Max = max(t[u].Max,t[rc].Max);
}
void ask(int u,Node x) {
    if(!u) return;
    if(t[u].Max <= ans) return;
    for(int i = 0;i < 4;i++) if(t[u].mi[i] > x.s[i]) return;
    if(x.s[0] >= t[u].mx[0] && x.s[1] >= t[u].mx[1] && x.s[2] >= t[u].mx[2] && x.s[3] >= t[u].mx[3]) 
    {ans = max(ans,t[u].Max);};
    if(x.s[0] >= t[u].p.s[0] && x.s[1] >= t[u].p.s[1] && x.s[2] >= t[u].p.s[2] && x.s[3] >= t[u].p.s[3]) 
    {ans = max(ans,t[u].p.val);}
    ask(t[u].ch[0],x);ask(t[u].ch[1],x);
}
void insert(int &u,Node x,int type) {
    if(!u) {
        u = ++size;t[u].p = x;pushup(u);return;
    }
    if(x.s[type] <= t[u].p.s[type]) insert(t[u].ch[0],x,(type+1)%4);
    else insert(t[u].ch[1],x,(type+1)%4);
    pushup(u);
}
int main() {
     // freopen("111.in","r",stdin);
    n = read();
    for(int i = 1;i <= n;i++) {
        for(int j = 0;j < 4;j++) A[i].s[j] = read();

    }
    sort(A + 1,A + 1 + n,cmp);
    for(int i = 1;i <= n;i++) {
        ans = -1;
        ask(rt,A[i]);
        if(ans != -1) A[i].val = ans + 1;
        else A[i].val = 1;
        insert(rt,A[i],0);
        Ans = max(ans + 1,Ans);
    }
    printf("%d\n",Ans);
    return 0;
}