zoukankan      html  css  js  c++  java
  • [TJOI2013]最长上升子序列

    [TJOI2013]最长上升子序列

    题面

    链接

    题解

    题目要求在插入数的时候维护最长上升子序列

    显然当不维护插入数这一操作时,可以直接DP解决

    观察题目,每次插入的数为当前数列最大数

    所以此时整个数列最长上升子序列只有两种情况一种是以当前数为结尾,另一种是不为结尾

    所以插入数并不会对之前的答案影响

    考虑用splay维护,当以当前数为根时,答案不是是以他左子树里的一点为结尾,就是以插入的数为结尾

    只需在每个叶节点记录即可

    插入时将要插入节点位置旋转到位置X后

    只需要先将X转到根,在讲X+1转到根的右儿子,插入到位置X+1的左儿子即可

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int MAXN = 100000 + 10;
    
    inline int read()
    {
        int f=1,x=0;
        char ch;
        do
        {
            ch=getchar();
            if(ch=='-') f=-1;
        }while(ch<'0'||ch>'9');
        do
        {
            x=(x<<3)+(x<<1)+ch-'0';
            ch=getchar();
        }while(ch>='0'&&ch<='9');
        return f*x;
    }
    
    struct Splay
    {
        int root;
        int idx;
        int ch[MAXN][2];
        int val[MAXN];
        int fa[MAXN];
        int sz[MAXN];
        int ma[MAXN];
        int dp[MAXN];
        inline int chk(int x)
        {
            return x==ch[fa[x]][1];
        }
        inline void pushup(int x)
        {
            sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
            ma[x]=max(ma[ch[x][0]],max(ma[ch[x][1]],dp[x]));
        }
        inline void rotate(int x)
        {
            int f=fa[x],gf=fa[f];
            int k=chk(x);
            ch[gf][chk(f)]=x;fa[x]=gf;
            ch[f][k]=ch[x][k^1];fa[ch[x][k^1]]=f;
            ch[x][k^1]=f;fa[f]=x;
            pushup(f);pushup(x);
            return;
        }
        inline void splay(int x,int goal)
        {
            while(fa[x]!=goal)
            {
                int f=fa[x],gf=fa[f];
                if(gf!=goal)
                {
                    if(chk(x)==chk(f)) rotate(f);
                    else rotate(x);
                }
                rotate(x);
            }
            if(!goal) root=x;
        }
        inline void insert(int x)
        {
            int cur=root,f=0;
            while(cur&&val[cur]!=x)
            {
                f=cur;
                if(val[cur]>ch[cur][0]) cur=ch[cur][0];
                else cur=ch[cur][1];
            } 
            cur=++idx;fa[cur]=f;
            if(f) ch[f][x>val[f]]=x;
            sz[cur]=1;
            ch[cur][0]=ch[cur][1]=0;
            val[cur]=x;
            if(!root) root=cur;
            splay(cur,0);
        }
        inline int kth(int k)
        {
            int cur=root;
            while(1)
            {
                if(k<=sz[ch[cur][0]])
                {
                    cur=ch[cur][0];
                }
                else if(k==sz[ch[cur][0]]+1) return cur;
                else k-=sz[ch[cur][0]]+1,cur=ch[cur][1];
            }
        }
    }tree;
    
    int n;
    
    int main()
    {
        n=read();
        tree.insert(n+1);
        tree.insert(0);
        for(int i=1;i<=n;i++)
        {
            int x=read();x++;
            int l=tree.kth(x);
            int r=tree.kth(x+1);
            tree.splay(l,0);
            tree.splay(r,l);
            int t=tree.ch[tree.root][1];
            tree.ch[t][0]=++tree.idx;
            int hhd=tree.ch[t][0];
            tree.fa[tree.ch[t][0]]=t;tree.val[tree.ch[t][0]]=i;
            tree.ch[hhd][0]=tree.ch[hhd][1]=0;
            tree.sz[hhd]=1;tree.splay(hhd,0);
            tree.dp[hhd]=tree.ma[tree.ch[hhd][0]]+1;
            tree.pushup(hhd);
            printf("%d
    ",tree.ma[hhd]);
        }
    }
  • 相关阅读:
    IDEA 工具 破解码
    postman 使用 及断言
    MonkeyTest 命名
    Jmeter 测试单元的封装与复用
    开发性能测试工具——自己动手实现迭代功能
    jemter安装mysql数据驱动JDBC
    全链路性能测试知识点整理
    Java接口全链路优化:如何降低接口RT时长(转)
    测试自动化之Mock服务思路探讨
    算法分析与设计(一)时间与空间复杂度
  • 原文地址:https://www.cnblogs.com/wlzs1432/p/11166854.html
Copyright © 2011-2022 走看看