• hihocoder1475 数组分拆【DP+前缀和优化】


    思路:

    DP[ i ] 代表以 i 结尾的方案数. dp[i] += sum[i] - sum[j - 1] != 0 ? dp[j] : 0 ;

    对于100%的数据,满足1<=N<=105, |Ai|<=100
    n 1e5呀,两层for,GG;
    利用树状数组维护sum[i],存的是以sum[i]的方案数 ,
    那么每次加上当前所有的方案,减去sum[i]的方案,就好了。
    这里还有一个小问题就是 |sum[i]|<=1e7,所以先离散化一下就好了。
    把当前所有前缀和的方案数加起来。。然后减掉以自己的方案数。

    也可以用map.


    树状数组维护。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const LL mod=1e9+7;
    const int N=1e5+10;
    LL sval[N],sum[N];
    LL dp[N];
    int lowbit(int x)
    {
        return x&(-x);
    }
    LL Sum(int d)
    {
        LL ans=0;
        while(d)
        {
            ans=(ans+sval[d])%mod;
            d=d-lowbit(d);
        }
        return ans;
    }
    
    void add(int d,LL val,int n)
    {
        while(d<=n)
        {
            sval[d]=(sval[d]+val)%mod;
            d+=lowbit(d);
        }
    }
    
    vector<LL>xs;
    int main()
    {
        LL n,a;
        scanf("%lld",&n);
        sum[0]=0;
        xs.push_back(0);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a);
            sum[i]=sum[i-1]+a;
            xs.push_back(sum[i]);
        }
        sort(xs.begin(),xs.end());
        auto it=unique(xs.begin(),xs.end());
        for(int i=0;i<=n;i++)
            sum[i]=lower_bound(xs.begin(),it,sum[i])-xs.begin()+1;
        memset(dp,0,sizeof(dp));
        for(int i=0;i<=n;i++)
        {
            dp[i]+=Sum(xs.size());
            dp[i]-=Sum(sum[i])-Sum(sum[i]-1);
            dp[i]=(dp[i]+mod)%mod;
            if(dp[i]==0)
                dp[i]=1;
            add(sum[i],dp[i],xs.size());
        }
        printf("%lld
    ",dp[n]);
        return 0;
    }
    
    

    map维护

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const LL mod=1e9+7;
    const int N=1e5+10;
    LL sum[N];
    LL dp[N];
    map<int,int>mp;
    
    int main()
    {
        LL n,a;
        scanf("%lld",&n);
        sum[0]=0;
        mp.clear();
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a);
            sum[i]=sum[i-1]+a;
        }
        memset(dp,0,sizeof(dp));
        dp[0]=1;
        mp[0]=1;
        LL cnt=1;
        for(int i=1;i<=n;i++)
        {
            if(!mp.count(sum[i]))
            {
                dp[i]=cnt;
                mp[sum[i]]=dp[i];
            }
            else
            {
                dp[i]=((cnt-mp[sum[i]])%mod+mod)%mod;
                mp[sum[i]]=(mp[sum[i]]+dp[i]+mod)%mod;
            }
            cnt=(cnt+dp[i]+mod)%mod;
        }
        printf("%lld
    ",dp[n]);
        return 0;
    }
    
    


  • 相关阅读:
    asp.net webapi 无法使用多个post,浏览器不支持put delete,405错误
    vs2019 nable-migrations : 无法将“enable-migrations”项识别为 cmdlet 使用“1”个参数调用“LoadFrom”时发生异常:“ EntityFramew
    javascript 扩展运算符(spread)三个点(...)的作用及用法
    PIE SDK元素的选择和取消选择
    PIE SDK元素的删除
    PIE SDK元素事件的监听
    PIE SDK临时元素的绘制
    PIE SDK图片元素的绘制
    PIE SDK文本元素的绘制
    PIE SDK面元素的绘制
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/6777389.html
Copyright © 2020-2023  润新知