• 【bzoj4553】[Tjoi2016&Heoi2016]序列【树套树 树状数组套平衡树】


    洛谷传送门
    大视野传送门
    这道题刚开始看上去没有思路,不过慢慢分析有了。
    我们设3个数组:
    a[i]表示原来第i个位置上的值。
    maxn[i]表示第i个位置上可以变成的最大值。
    minn[i]表示第i个位置上可以变成的最小值。
    要满足在任意一种变化中,选出的子序列中第i个位置的上一个位置j是符合要求的,需要满足:
    1.j<i 这一条很显然。
    2.maxn[j]<=a[i] 当j的位置上的数变成最大值时序列仍然不降。
    3.a[j]<=minn[i] 当i的位置上的数变成最小值时序列仍然不降。
    于是一个dp就很显然了:
    f[i]=max(f[j]),j要满足上述条件。
    可以发现,有1,2,3这3条要求,不就是一个三维偏序问题吗?跟陌上花开那道题非常像。
    首先从小到大枚举i,可以降掉第一维。
    第二维和第三维直接树套树搞定。
    我写了树状数组套Treap,时间复杂度和空间复杂度都是比较稳的。
    第一次1A树套树祭
    代码:

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    const int N=100005;
    int n,m,k,x,y,ans=1,a[N],maxn[N],minn[N],f[N];
    int cnt,ch[N*16][2],siz[N*16],val[N*16],key[N*16],mx[N*16],rnd[N*16];
    struct Treap{
        int rt;
        void pushup(int k){
            siz[k]=siz[ch[k][0]]+siz[ch[k][1]]+1;
            mx[k]=max(max(mx[ch[k][0]],mx[ch[k][1]]),key[k]);
        }
        void rotate(int &y,int md){
            int x=ch[y][md];
            ch[y][md]=ch[x][!md];
            ch[x][!md]=y;
            pushup(y);
            pushup(x);
            y=x;
        }
        void insert(int &k,int v,int x){
            if(!k){
                k=++cnt;
                val[k]=v;
                key[k]=mx[k]=x;
                rnd[k]=rand();
                siz[k]=1;
                return;
            }
            siz[k]++;
            if(v==val[k]){
                key[k]=max(key[k],x);
            }else if(v<val[k]){
                insert(ch[k][0],v,x);
                if(rnd[ch[k][0]]>rnd[k]){
                    rotate(k,0);
                }
            }else{
                insert(ch[k][1],v,x);
                if(rnd[ch[k][1]]>rnd[k]){
                    rotate(k,1);
                }
            }
            pushup(k);
        }
        int query(int x){
            int k=rt,res=0;
            while(k){
                if(x==val[k]){
                    res=max(res,key[k]);
                    break;
                }else if(x<val[k]){
                    k=ch[k][0];
                }else{
                    res=max(res,max(key[k],mx[ch[k][0]]));
                    k=ch[k][1];
                }
            }
            return res;
        }
    }t[N];
    inline int lowbit(int x){
        return x&(-x);
    }
    void add(int i,int j,int v){
        while(i<=k){
            t[i].insert(t[i].rt,j,v);
            i+=lowbit(i);
        }
    }
    int qmax(int i,int j){
        int res=0;
        while(i){
            res=max(res,t[i].query(j));
            i-=lowbit(i);
        }
        return res;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            maxn[i]=minn[i]=a[i];
        }
        for(int i=1;i<=m;i++){
            scanf("%d%d",&x,&y);
            maxn[x]=max(maxn[x],y);
            minn[x]=min(minn[x],y);
            k=max(k,maxn[x]);
        }
        f[1]=1;
        add(maxn[1],a[1],1);
        for(int i=2;i<=n;i++){
            f[i]=qmax(a[i],minn[i])+1;
            add(maxn[i],a[i],f[i]);
            ans=max(ans,f[i]);
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    深度卷积网络中如何进行上采样?
    权重衰减(weight decay), L2正则
    python中的super().__init__()
    随机变量的间独立性及其传播
    卡尔曼滤波、扩展卡尔曼滤波、无迹卡尔曼滤波以及粒子滤波原理
    贝叶斯推断中的后验概率、似然函数、先验概率以及边际似然定义(转)
    详解最大似然估计(MLE)、最大后验概率估计(MAP),以及贝叶斯公式的理解(转)
    python告警发微信
    python模块operator操作符函数
    Django之CSRF验证。
  • 原文地址:https://www.cnblogs.com/2016gdgzoi471/p/9476897.html
Copyright © 2020-2023  润新知