zoukankan      html  css  js  c++  java
  • 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
    ",mmax);
            change(q[i].id,L);
        }
        return 0;
    }
  • 相关阅读:
    Linux Home目录硬盘空间缩减
    test
    ORACLE 数据泵 expdp/impdp
    mysql利用mysqlbinlog命令恢复误删除数据
    LogMiner日志挖掘分析管理
    Oracle 审计测试与总结
    redis 5.0.3 讲解、集群搭建
    联想服务器配置 RAID
    Cenots7对lvm逻辑卷分区大小的调整
    kvm 基本运维命令
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8540374.html
Copyright © 2011-2022 走看看