題解
以後看到冪和並且冪次比較小的時候儘量往斯特林數方面想
關於題解,有一個巧妙的巧妙的實現就是把 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");
}
}