zoukankan      html  css  js  c++  java
  • BZOJ3173 TJOI2013最长上升子序列(splay)

      容易发现如果求出最后的序列,只要算一下LIS就好了。序列用平衡树随便搞一下,这里种一棵splay。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 100010
    int n,tree[N],cnt=0;
    struct data
    {
        int x,f;
        bool operator <(const data&a) const
        {
            return x<a.x;
        }
    }a[N];
    namespace Splay
    {
        struct data{int fa,ch[2],s;}tree[N];
        int root=0;
        int whichson(int k){return tree[tree[k].fa].ch[1]==k;}
        void up(int k){tree[k].s=tree[tree[k].ch[0]].s+tree[tree[k].ch[1]].s+1;}
        void move(int k)
        {
            int fa=tree[k].fa,gf=tree[fa].fa,p=whichson(k);
            if (fa) tree[gf].ch[whichson(fa)]=k;tree[k].fa=gf;
            tree[fa].ch[p]=tree[k].ch[!p],tree[tree[k].ch[!p]].fa=fa;
            tree[k].ch[!p]=fa,tree[fa].fa=k;
            up(fa),up(k);
        }
        void splay(int k)
        {
            while (tree[k].fa)
            {
                int fa=tree[k].fa;
                if (tree[fa].fa)
                    if (whichson(fa)^whichson(k)) move(k);
                    else move(fa);
                move(k);
            }
            root=k;
        }
        void ins(int &k,int s,int x,int from)
        {
            if (!k) {k=x,tree[k].s=1,tree[k].fa=from;return;}
            if (tree[tree[k].ch[0]].s>=s) ins(tree[k].ch[0],s,x,k);
            else ins(tree[k].ch[1],s-tree[tree[k].ch[0]].s-1,x,k);
        }
        void dfs(int k)
        {
            if (tree[k].ch[0]) dfs(tree[k].ch[0]);
            a[++cnt].x=k;
            if (tree[k].ch[1]) dfs(tree[k].ch[1]);
        }
    }
    int query(int k){int s=0;while (k) s=max(s,tree[k]),k-=k&-k;return s;}
    void ins(int k,int x){while (k<=n) tree[k]=max(tree[k],x),k+=k&-k;}
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj3173.in","r",stdin);
        freopen("bzoj3173.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read();
        for (int i=1;i<=n;i++)
        {
            int x=read();
            Splay::ins(Splay::root,x,i,0);Splay::splay(i);
        }
        Splay::dfs(Splay::root);
        for (int i=1;i<=n;i++)
        a[i].f=query(a[i].x)+1,ins(a[i].x,a[i].f);
        sort(a+1,a+n+1);
        for (int i=1;i<=n;i++) a[i].f=max(a[i].f,a[i-1].f),printf("%d
    ",a[i].f);
        return 0;
    }
  • 相关阅读:
    【26】多任务学习
    【25】迁移学习
    【24】定位数据不匹配
    【23】不匹配数据划分的偏差和方差;判断问题所在的几个重要参数
    【22】在不同的划分上进行训练和测试
    【21】进行误差分析
    17-----vue-cli脚手架安装和webpack-simple模板项目生成
    15-----修饰符
    14-----表单输入绑定
    12-----指令系统介绍
  • 原文地址:https://www.cnblogs.com/Gloid/p/9670910.html
Copyright © 2011-2022 走看看