CodeForces 520E. Pluses everywhere 字符串,组合数学

8 篇文章 1 订阅
8 篇文章 1 订阅

题意:给定长度为n的数字串,在空隙添上k个+号,可以得到一个式子,求出插入k个+号可以得到的所有式子的计算结果之和

公式题:

代码中a[i]与上面公式中是反的,代码中a[i]是从左往右的。

在对M=10^9 +7 取模的情况下,计算组合数C(n,k)可以预处理fac[i](i 的阶乘)和 revfac[i](i 在模M下的乘法逆)

然后线性递推一下系数数组,最后求和。

要说明的是,代码中的C(n,k)没有处理n<0而k>=0的情况(这时不一定为0,而代码中直接令它为0)

所以上述公式直接使用会有误差,于是代码中特判了k=0的情况,避免组合数出问题。



代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#define maxn 100007
#define M 1000000007
#define LL long long
using namespace std;
LL fac[maxn];
LL ten[maxn];
LL revfac[maxn];
LL QuickPower(LL a,LL k){//快速幂
	LL ANS=1;
	while(k){
		if(k&1) ANS=(ANS*a)%M;
		k>>=1;
		a=(a*a)%M;
	}
	return ANS;
}
LL C(LL n,LL k){//组合数
	if(k<0||k>n ||n <0) return 0;
	LL ANS=fac[n];
	ANS=(ANS*revfac[k])%M;
	ANS=(ANS*revfac[n-k])%M;
	return ANS;
}
void Init(){//初始化阶乘fac数组以及阶乘乘法逆revfac数组
	ten[0]=fac[0]=revfac[0]=1;
	for(int i=1;i<maxn;++i){
		fac[i]=(i*fac[i-1])%M;
		revfac[i]=QuickPower(fac[i],M-2);
		ten[i]=(10*ten[i-1])%M;
	}
}
int n,k;
char str[maxn];
LL Coef[maxn];
int main(void)
{
	Init();
	while(~scanf("%d%d",&n,&k)){
		scanf("%s",str);
		if(k==0){
			LL ANS=0;
			for(int i=0;i<n;++i) ANS=(ANS+ten[i]*(str[n-i-1]-'0'))% M;
			printf("%d\n",(int)ANS);
			continue;
		}
		int D=n-k-1;//计算系数
		Coef[0]=C(n-2,k-1);
		for(int i=1;i<=D;++i) Coef[i]=(Coef[i-1]+ten[i]*C(n-i-2,k-1))% M;
		for(int i=D+1;i<n;++i) Coef[i]=Coef[i-1];
		for(int i=0;i<=D;++i) Coef[i]=(Coef[i]+ten[i]*C(n-i-2,k))% M;
		
		LL ANS=0;//计算最终答案
		for(int i=0;i<n;++i){
			ANS=(ANS+Coef[n-i-1]*(str[i]-'0'))% M;
		}
		printf("%d\n",(int)ANS);
	}
return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
您提供的链接是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 ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值