CodeForces - 1422C - Bargain 枚举贡献

   日期:2020-10-07     浏览:94    评论:0    
核心提示:CodeForces - 1422C - Bargain 枚举贡献题意:给出长度为n的字符串,删除其中任意长度的连续子串,将所有可能的情况的数字加起来取模做法:假设序列是12354,假设2不被删去那么可能的情况有以下两种:删除位置[3,5]中的连续子串这种情况下,2的贡献是不同的,分别是:删除长度为3的子串2×100×12×10^0×12×100×1删除长度为2的子串:2×101×22×10^1×22×101×2删除长度为1的子串:2×102×32×10^2×32×102×3ans1=∑

CodeForces - 1422C - Bargain 枚举贡献

题意:给出长度为n的字符串,删除其中任意长度的连续子串,将所有可能的情况的数字加起来取模

做法:假设序列是12354,假设2不被删去
那么可能的情况有以下两种:

  • 删除位置[3,5]中的连续子串
    这种情况下,2的贡献是不同的,分别是:
    删除长度为3的子串 2 × 1 0 0 × 1 2×10^0×1 2×100×1
    删除长度为2的子串: 2 × 1 0 1 × 2 2×10^1×2 2×101×2
    删除长度为1的子串: 2 × 1 0 2 × 3 2×10^2×3 2×102×3
    a n s 1 = ∑ i = 1 n ( ( s [ i ] − ′ 0 ′ ) × ∑ j = 1 n − i j 1 0 j − 1 ) ans1=\sum_{i=1}^{n}((s[i]-'0')×\sum_{j=1}^{n-i}j10^{j-1}) ans1=i=1n((s[i]0)×j=1nij10j1)
  • 删除位置[1,1]中的连续子串
    这种情况下,2的贡献是相同的,只需要算有多少种情况即可
    a n s 2 = ∑ i = 1 n ( ( s [ i ] − ′ 0 ′ ) × 1 0 n − i × i ( i − 1 ) / 2 ) ans2=\sum_{i=1}^{n}((s[i]-'0')×10^{n-i}×i(i-1)/2) ans2=i=1n((s[i]0)×10ni×i(i1)/2)

输出ans1+ans2即可

代码

const int maxn=2e6+7;
const int INF=0x3f3f3f3f;
const ll INFF=1e18;
const ll mod=1e9+7;
char s[maxn];
ll f[maxn],ans=0,n;
ll qpow(ll a,ll b,ll mod){ ll res=1;while(b){ if (b&1)res=(res*a)%mod;a=a*a%mod;b>>=1;}return res;}
int main()
{ 
    scanf("%s",s+1);
    n=strlen(s+1);
    rep(i,1,n)f[i]=(f[i-1]+(i*qpow(10,i-1,mod)%mod))%mod;
    for (ll i=n;i>=1;i--)
    { 
        ans=(ans+f[n-i]*(s[i]-'0')%mod)%mod;
        ans=(ans+(s[i]-'0')*qpow(10,n-i,mod)%mod*((i*(i-1)/2)%mod)%mod)%mod;
    }
    WW(ans);
    return 0;
}

拓展:一开始读错题了,以为是删去任意长度的子序列(不一定连续),这种情况下,可以直接线性递推,假设 [ 1 , i ] [1,i] [1,i]的串可以构成的答案是ans,把 s [ i + 1 ] s[i+1] s[i+1]放进来

  • 如果取它,那么之前的答案相当于左移一位=10ans,并且计算出有多少个新加进来的 s [ i + 1 ] s[i+1] s[i+1]
  • 如果不取它,仍然是ans

由于不能一个都不删,所以得把它自身减去就是答案了

代码

const int maxn=2e6+7;
const int INF=0x3f3f3f3f;
const ll INFF=1e18;
const ll mod=1e9+7;
char s[maxn];
ll qpow(ll a,ll b,ll mod){ ll res=1;while(b){ if (b&1)res=(res*a)%mod;a=a*a%mod;b>>=1;}return res;}
int main()
{ 
    scanf("%s",s+1);
    int n=strlen(s+1);
    ll x=0,ans=0;
    for(int i=n;i>=1;i--)x=(x+qpow(10,n-i,mod)*(s[i]-'0')%mod)%mod;
    rep(i,1,n)ans=(ans*11%mod+qpow(2,i-1,mod)*(s[i]-'0')%mod)%mod;
    WW((ans-x+mod)%mod);
    return 0;
}
 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服