BZOJ 3173: [Tjoi2013]最长上升子序列 Splay

一眼切~

重点是按照 $1$~$n$ 的顺序插入每一个数,这样的话就简单了.  

#include <cstdio> 
#include <algorithm>
#define N 100004 
#define lson t[x].ch[0] 
#define rson t[x].ch[1] 
#define setIO(s) freopen(s".in","r",stdin)   , freopen(s".out","w",stdout) 
using namespace std;  
int cnt,root,n;  
struct Node 
{
    int ch[2],f,maxv,siz,val;        
}t[N]; 
inline void pushup(int x) 
{
    t[x].siz=t[lson].siz+t[rson].siz+1; 
    t[x].maxv=max(t[x].val,max(t[lson].maxv,t[rson].maxv));        
}
inline int get(int x) { return t[t[x].f].ch[1]==x; } 
inline void rotate(int x) 
{
    int old=t[x].f,fold=t[old].f,which=get(x); 
    t[old].ch[which]=t[x].ch[which^1],t[t[old].ch[which]].f=old; 
    t[x].ch[which^1]=old,t[old].f=x,t[x].f=fold; 
    if(fold) t[fold].ch[t[fold].ch[1]==old]=x; 
    pushup(old),pushup(x); 
}
inline void splay(int x,int &tar) 
{
    int u=t[tar].f; 
    for(int fa;(fa=t[x].f)!=u;rotate(x)) 
        if(t[fa].f!=u) 
            rotate(get(fa)==get(x)?fa:x); 
    tar=x; 
}
void insert(int &x,int ff,int pos,int v) 
{ 
    if(!x) 
    {
        x=++cnt,t[x].f=ff,t[x].val=v,pushup(x); 
        return; 
    }
    int lsize=t[lson].siz; 
    if(pos<=lsize+1) insert(lson,x,pos,v); 
    else insert(rson,x,pos-lsize-1,v);                                     
    pushup(x);   
}
inline int find(int kth) 
{ 
    int x=root; 
    while(1) 
    { 
        if(t[lson].siz+1==kth) return x;   
        if(t[lson].siz>=kth) x=lson; 
        else kth-=(t[lson].siz+1), x=rson; 
    }
}
void debug(int x) {
    if(lson) debug(lson); 
    printf("%d ",t[x].val); 
    if(rson) debug(rson); 
}
int main() 
{
    int i,j,ans=0; 
    // setIO("input");     
    scanf("%d",&n);  
    for(i=1;i<=n;++i) 
    {
        int k,lst; 
        scanf("%d",&k);   
        if(k==0) lst=1; 
        else if(k==i-1) lst=t[root].maxv+1;                       
        else 
        {
            splay(find(k+1),root);  
            lst=t[t[root].ch[0]].maxv+1;                      
        }
        insert(root,0,k+1,lst), splay(cnt,root); 
        // printf("%d\n",t[root].val); 
        printf("%d\n",t[root].maxv);   
    }
    return 0; 
}

  

posted @ 2019-08-22 20:16  EM-LGH  阅读(151)  评论(0编辑  收藏  举报