zoukankan      html  css  js  c++  java
  • P3970 [TJOI2014]上升子序列

    传送门

    上升子序列 就是满足严格递增

    先考虑大体思路:

    如果题目没有要求“如果两个上升子序列相同,那么只需要计算一次”,那么就非常友好了

    dp转移方程也很简单 

    dp[i]=Σdp[j](0<j<i)

    但是现在要求相同的只能记一次

    我们考虑用一个数组la(lastans)[]记录

    那么这个数组的作用是什么呢?

    在a[i]第一次出现时 我们记录下它前面有多少个上升子序列

    即la[i]=子序列个数

    在a[i]第二次出现时 仍然先计算它前面上升子序列的个数(假设为ans1) 

    但因为其中有一部分已经在第一次遇到a[i]时求解过了

    所以我们用ans1-la[a[i]] 

    这就是第一个a[i]与第二个a[i]之间上升子序列的个数

    具体细节:

    如果用一般dp的方法求解 大概只能过前30%

    对于100% 的数据 我们考虑用树状数组优化(安利

    这样复杂度可以从O(n^2)降到O(nlogn)

    最后不要忘记离散化

    具体看代码啦

    #include<bits/stdc++.h>
    using namespace std;
    const int mod=1e9+7;
    const int mxn=1e5+5;
    typedef long long ll;
    ll a[mxn],b[mxn],ans;
    int n,sz;
    bool v[mxn];
    ll ld[mxn],f[mxn];
    ll lowbit(ll x){
        return x&(-x);
    }
    void motify(ll x,ll w){
        for(;x<=n;x+=lowbit(x)){
            f[x]=(f[x]+w)%mod;
        }
    }
    ll get(ll x){
        ll temp=0;
        for(;x;x-=lowbit(x)){
            temp=(temp+f[x])%mod;
        }
        return temp;
    }
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            b[i]=a[i];
        }
        sort(b+1,b+n+1);
        sz=unique(b+1,b+n+1)-(b+1);
        for(int i=1;i<=n;i++){
            a[i]=lower_bound(b+1,b+sz+1,a[i])-b;
        }
        ans=0;
        for(int i=1;i<=n;i++){
            if(!v[a[i]]){
                v[a[i]]=1;
                ll t=get(a[i]-1);
                ans=(ans+t)%mod;
                ld[a[i]]=t;
                motify(a[i],t+1);
                continue;
            }
            v[a[i]]=1;
            ll t=get(a[i]-1);
            ans=(ans+t-ld[a[i]]+mod)%mod;
            motify(a[i],(t-ld[a[i]]+2*mod)%mod);
            ld[a[i]]=t;
        }
        std::cout<<ans;
        return 0;
    }
  • 相关阅读:
    3D打印技术大潮
    有用网址
    linux下scp命令详解
    使用 GDB 调试多进程程序
    linux下top命令参数解释
    Sql动态查询拼接字符串的优化
    vmstat参数详解
    freebsd破解密码
    freebsd防火墙
    freebsd无法输入汉字
  • 原文地址:https://www.cnblogs.com/duojiaming/p/11674038.html
Copyright © 2011-2022 走看看