bzoj3173: [Tjoi2013]最长上升子序列
用splay离线弄好顺序。
然后树状数组(分治也行吧)
看错题Wa了。。。是当前所有最大值不是包含插入这个数字子序列的最大值。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; struct node { int d,c,f,son[2]; }tr[110000];int len,root; void update(int x) { int lc=tr[x].son[0],rc=tr[x].son[1]; tr[x].c=tr[lc].c+tr[rc].c+1; } void rotate(int x,int w) { int f=tr[x].f,ff=tr[f].f; int r,R; r=tr[x].son[w];R=f; tr[R].son[1-w]=r; if(r!=0)tr[r].f=R; r=x;R=ff; if(tr[R].son[0]==f)tr[R].son[0]=r; else tr[R].son[1]=r; tr[r].f=R; r=f;R=x; tr[R].son[w]=r; tr[r].f=R; update(f); update(x); tr[0].c=0;tr[0].f=0; tr[0].son[0]=tr[0].son[1]=0; } void splay(int x,int rt) { while(tr[x].f!=rt) { int f=tr[x].f,ff=tr[f].f; if(ff==rt) { if(tr[f].son[0]==x)rotate(x,1); else rotate(x,0); } else { if(tr[ff].son[0]==f&&tr[f].son[0]==x){rotate(f,1);rotate(x,1);} else if(tr[ff].son[1]==f&&tr[f].son[1]==x){rotate(f,0);rotate(x,0);} else if(tr[ff].son[0]==f&&tr[f].son[1]==x){rotate(x,0);rotate(x,1);} else if(tr[ff].son[1]==f&&tr[f].son[0]==x){rotate(x,1);rotate(x,0);} } } if(rt==0)root=x; } void ins(int d,int p) { if(root==0) { len++;root=len; tr[len].d=d;tr[len].c=1; tr[len].son[0]=tr[len].son[1]=0; tr[len].f=0; return ; } int now=root; while(1) { int lc=tr[now].son[0],rc=tr[now].son[1]; if(tr[lc].c==p) { int rig=lc; while(tr[rig].son[1]!=0)rig=tr[rig].son[1]; if(rig==0) { len++; tr[len].d=d;tr[len].c=1; tr[len].son[0]=tr[len].son[1]=0; tr[len].f=now;tr[now].son[0]=len; update(now);splay(now,0); return ; } else { splay(rig,now); len++; tr[len].d=d;tr[len].c=1; tr[len].son[0]=tr[len].son[1]=0; tr[len].f=rig;tr[rig].son[1]=len; update(rig);splay(rig,0); return ; } } else if(tr[lc].c+1==p) { int lef=rc; while(tr[lef].son[0]!=0)lef=tr[lef].son[0]; if(lef==0) { len++; tr[len].d=d;tr[len].c=1; tr[len].son[0]=tr[len].son[1]=0; tr[len].f=now;tr[now].son[1]=len; update(now);splay(now,0); return ; } else { splay(lef,now); len++; tr[len].d=d;tr[len].c=1; tr[len].son[0]=tr[len].son[1]=0; tr[len].f=lef;tr[lef].son[0]=len; update(lef);splay(lef,0); return ; } } else if(tr[lc].c>p)now=lc; else if(tr[lc].c+1<p)now=rc,p-=tr[lc].c+1; } } //------------splay--------------- int n; int s[110000]; int lowbit(int x){return x&-x;} void change(int x,int k) { while(x<=n) { s[x]=max(s[x],k); x+=lowbit(x); } } int getmax(int x) { int ret=0; while(x>=1) { ret=max(s[x],ret); x-=lowbit(x); } return ret; } struct query { int x,id; }q[110000];int qlen,cnt; bool cmp(query n1,query n2) { return n1.x<n2.x; } void dfs(int x) { if(tr[x].son[0]!=0)dfs(tr[x].son[0]); qlen++; q[qlen].x=tr[x].d,q[qlen].id=++cnt; if(tr[x].son[1]!=0)dfs(tr[x].son[1]); } int main() { freopen("data.in","r",stdin); freopen("lj.out","w",stdout); int p; scanf("%d",&n); len=0;root=0; for(int i=1;i<=n;i++) { scanf("%d",&p); ins(i,p); } qlen=0;cnt=0;dfs(root); sort(q+1,q+qlen+1,cmp); int mmax=0; for(int i=1;i<=qlen;i++) { int L=getmax(q[i].id-1)+1; mmax=max(L,mmax); printf("%d\n",mmax); change(q[i].id,L); } return 0; }
pain and happy in the cruel world.