CodeForces 520E. Pluses everywhere 字符串,組合數學

題意:給定長度爲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;
}



發佈了96 篇原創文章 · 獲贊 375 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章