直接用一颗splay维护这个序列。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 100050 using namespace std; int n,x,size[maxn],fath[maxn],tree[maxn][3],mx[maxn],f[maxn],root,tot=0; void reset() { root=1;tot=2;tree[1][2]=2;fath[2]=1; mx[1]=mx[2]=0;size[1]=2;size[2]=1; } void pushup(int x) { size[x]=size[tree[x][1]]+size[tree[x][2]]+1; mx[x]=max(f[x],max(mx[tree[x][1]],mx[tree[x][2]])); } int find_kth(int now,int k) { if (tree[now][1]==0 && tree[now][2]==0) return now; int r=size[tree[now][1]]; if (k<=r) return find_kth(tree[now][1],k); else if (r+1==k) return now; else return find_kth(tree[now][2],k-r-1); } void rotate(int x,int &k) { int y=fath[x],z=fath[y],l,r; if (tree[y][1]==x) l=1;else l=2;r=3-l; if (y==k) k=x; else { if (tree[z][1]==y) tree[z][1]=x; else tree[z][2]=x; } fath[x]=z;fath[y]=x;fath[tree[x][r]]=y; tree[y][l]=tree[x][r];tree[x][r]=y; pushup(y);pushup(x); } void splay(int x,int &k) { while (x!=k) { int y=fath[x],z=fath[y]; if (y!=k) { if ((tree[y][1]==x)^(tree[z][1]==y)) rotate(x,k); else rotate(y,k); } rotate(x,k); } } void insert(int x,int y,int z) { fath[y]=z;fath[z]=x;tree[z][1]=y;tree[x][1]=z; pushup(z);pushup(x);splay(y,root); } int main() { scanf("%d",&n); reset(); for (int i=1;i<=n;i++) { scanf("%d",&x); int pos=find_kth(root,x+2); splay(pos,root); pos=find_kth(root,x+1); splay(pos,tree[root][1]); f[i+2]=mx[tree[root][1]]+1; insert(root,pos,i+2); printf("%d\n",mx[root]); } return 0; }