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;
}

 

posted @ 2018-03-10 15:59  AKCqhzdy  阅读(163)  评论(0编辑  收藏  举报