省選模擬賽第八場 算算算(巧用斯特林數+維護下降冪)

 

 

 

題解

以後看到冪和並且冪次比較小的時候儘量往斯特林數方面想

關於題解,有一個巧妙的巧妙的實現就是把 i!乘進組合數

接下來就只需要維護每個值+1之後的下降k次冪之和(把k取0~100的下降冪之和都要動態維護)

想了我好久。。。

後來看到了標程,就一句話f[i][k]=f[i-1][k-1]*i+f[i-1][k],妙啊!!!!

展開一下,發現每個數的下降k-1次冪都可以提出來,相當於給最後一個數加上i

而最後一個數加上i就剛好使k次下降冪變成了k+1次下降冪

代碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 105
const int mod=1000000007;
int S[N][N],f[N];
char ch[50005];
int main()
{
	freopen("number.in","r",stdin);
	freopen("number.out","w",stdout);
	int T,n,k,i,j,ans=0;
	scanf("%d",&T);
	for(i=1;i<=100;i++){
		S[i][1]=S[i][i]=1;
		for(j=2;j<i;j++)
			S[i][j]=(1ll*S[i-1][j]*j+1ll*S[i-1][j-1])%mod;
	}
	while(T--){
		memset(f,0,sizeof(f));
		scanf("%d%d%s",&n,&k,ch+1);
		for(i=1;i<=n;i++){
			ans=0;
			f[0]++;if(f[0]>=mod)f[0]-=mod;
			while(ch[i]-->'0')
				for(j=k;j>=1;j--)
					f[j]=(1ll*f[j]+1ll*f[j-1]*j)%mod;// miao a
			for(j=0;j<=k;j++)
				ans=(1ll*ans+1ll*S[k][j]*f[j])%mod;
			printf("%d",ans);
			if(i<n)printf(" ");
		}
		printf("\n");
	}
}

 

 

 

 

 

 

 

 

 

 

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