Codeforces 520E/521C Pluses everywhere

转载请注明出处,谢谢http://blog.csdn.net/bigtiao097?viewmode=contents

题意

给定长度为n的数字串,在空隙添上k个+号(每个空隙最多添加一个),得到合法的加法式子,求上述得到的所有的式子的计算结果之和%1e9+7
(0k<n1e5)

思路

考虑每个数字对答案的贡献值,总共有n-1个位置可以放加号。下文中左边指高位,右边指地位。
对于一个数字x来说,考虑以下情况:

  • 考虑其作个位时,也就是其右边第一个空隙为加号,那么其余k-1个加号随便放在剩下的n-2个位置就好了,这时对答案的贡献为x;
  • 其作十位数的时候,那么加号一定在其右边第二个空隙上,其余k-1个加号随便放在剩下的n-3个位置(除去x右边第一个空隙)就好了,这时对答案的贡献为10x
  • 以此类推……
  • 还有一种情况就是加号全部放在x的左边,这时对答案的贡献要根据x的位置来决定

但是问题来了,这样会使得复杂度成为 O(n2) ,显然不行
不过你会发现,上述过程有好多重复的工作,对于每个数考虑其右边第一个加号时过程几乎是一样的,只是考虑的次数不同,这样完全可以利用前面算出来的结果,求个前缀和,接着累加就行

最后的问题就是求组合数,提前处理好1~n的阶乘以及对1e9+7的逆元就好了


具体代码如下:
Result:Accepted    Memory:5272 KB   Time : 46ms

#include<bits/stdc++.h>
const int maxn = 1e5+5;
const int mod = 1e9+7;
using namespace std;
typedef long long ll;
ll fac[maxn];
ll inv[maxn];
ll sum[maxn];
char s[maxn];
ll a[maxn];
int n,k;
ll ans;
ll ten;
ll mod_pow(ll x,ll n)
{
    x%=mod;
    ll res = 1;
    while(n>0)
    {
        if(n&1) res = res*x%mod;
        x = x*x%mod;
        n>>=1;
    }
    return res;
}
void init()
{
    inv[0]=1;fac[0]=1;
    for(int i=1;i<=n;i++)
    {
        fac[i] = (fac[i-1]*i)%mod;
        inv[i] = mod_pow(fac[i],mod-2)%mod;
    }
}
ll C(ll n,ll m)
{
    if(n<0||m<0) return 0;
    if(m>n) return 0;
    return (((fac[n]*inv[m])%mod)*inv[n-m])%mod;
}
int main()
{
    cin>>n>>k;
    init();
    scanf("%s",s+1);
    for(int i=1;i<=n;i++)
        a[i] = s[i]-'0';
    ten = 1;
    for(int i=n-1;i>=1;i--)
    {
        sum[i] = (sum[i+1]+ten*C(i-1,k-1))%mod;
        //枚举右边第一个加号式,利用前面的计算结果
        ten = (ten*10)%mod;
    }
    ten = 1;
    for(int i=n;i>=k+1;i--)
    {
        sum[i] = (sum[i]+C(i-1,k)*ten)%mod;//考虑加号全部在左边
        ten = (ten*10)%mod;
    }
    ans = 0;
    for(int i=1;i<=n;i++)
        ans = (ans+sum[i]*a[i])%mod;
    cout<<ans<<endl;
}

您提供的链接是Codeforces的一个问题,问题编号为104377。Codeforces是一个知名的在线编程竞赛平台,经常举办各种编程比赛和训练。Gym是Codeforces的一个扩展包,用于组织私人比赛和训练。您提供的链接指向了一个问题的页面,但具体的问题内容和描述无法通过链接获取。如果您有具体的问题或需要了解关于Codeforces Gym的更多信息,请提供更详细的信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [http://codeforces.com/gym/100623/attachments E题](https://blog.csdn.net/weixin_30820077/article/details/99723867)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [http://codeforces.com/gym/100623/attachments H题](https://blog.csdn.net/weixin_38166726/article/details/99723856)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [CodeforcesPP:Codeforces扩展包](https://download.csdn.net/download/weixin_42101164/18409501)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值