• 51NOD 1376 最长递增子序列的数量 [CDQ分治]


    1376 最长递增子序列的数量


    首先可以用线段树优化$DP$做,转移时取$0...a[i]$的最大$f$值

    但我要练习$CDQ$

    $LIS$是二维偏序问题,偏序关系是$i<j, a_i<a_j$

    $CDQ$分治可以解决偏序问题

    $CDQ(l,r) :$

    $CDQ(l,mid)$

    $[l,r]$按$a$排序,$[l,mid] ightarrow [mid+1,r]$

    $CDQ(mid+1,r)$

    这个排序没法用归并排序,因为你要用最优的$f[k],kin [mid+1,r]$来更新$k$的右面,必须先$[l,mid] ightarrow [mid+1,r]$获得最优的$f[k]$才行,而那些计数类问题就不需要了

    我尝试了很多写法,最后分治里还是采用了间接排序,这样不影响$i<j$这个关系

    [2017-02-25]不排序用一个维护区间最大值的数据结构也可以,更新的时候取$0...a[i]$的最大$f$值(这样你还分治什么啊?!)

    注意严格递增

    于是$LIS$现在可以用$CDQ$水过啦!!!

    其实二维的最长上升子序列用$CDQ$分治是没有意义的,无论如何都比数据结构维护多一个$log$

    该死一下午就写这玩意了

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    const int N=5e4+5,MOD=1e9+7;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int n,a[N],ref[N];
    inline bool cmp(int x,int y){return a[x]==a[y]?x>y:a[x]<a[y];}//strict
    inline void mod(int &x){if(x>=MOD) x-=MOD;}
    int f[N],g[N];
    void CDQ(int l,int r){
        if(l==r) return;
        int mid=(l+r)>>1;
        CDQ(l,mid);
        for(int i=l;i<=r;i++) ref[i]=i;
        sort(ref+l,ref+r+1,cmp);
        int mx=0,cnt=0;
        for(int i=l;i<=r;i++){
            int id=ref[i];
            if(id<=mid){
                if(f[id]>mx) mx=f[id],cnt=g[id];
                else if(f[id]==mx) mod(cnt+=g[id]);
            }else{
                if(mx+1>f[id]) f[id]=mx+1,g[id]=cnt;
                else if(f[id]==mx+1) mod(g[id]+=cnt);
            }
        }
        CDQ(mid+1,r);
    }
    int main(){
        freopen("in","r",stdin);
        n=read();
        for(int i=1;i<=n;i++) a[i]=read(),f[i]=g[i]=1;
        CDQ(1,n);
        int mx=0,cnt=0;
        for(int i=1;i<=n;i++){
            if(f[i]>mx) mx=f[i],cnt=g[i];
            else if(f[i]==mx) mod(cnt+=g[i]);
        }
        printf("%d",cnt%MOD);
    }
  • 相关阅读:
    一则由表单提交引发的思考
    前端技术栈持续汇总中(已解锁)
    5599充值中心功能开发
    CSS动画持续汇总中
    编程小技巧持续汇总中
    开发软件安装方法汇总
    HashMap中tableSizeFor
    2019年JVM面试都问了什么?快看看这22道面试题!(附答案解析)
    Spring注解@EnableWebMvc使用坑点解析
    线程池中 work 为何要实现 AbstractQueuedSynchronizer
  • 原文地址:https://www.cnblogs.com/candy99/p/6439193.html
Copyright © 2020-2023  润新知