北京區域賽I題,Uva7676,A Boring Problem,字首和差分
阿新 • • 發佈:2018-12-19
A Boring Problem
題解
其實這題不難,只要想到了字首和差分就基本OK了.
我們要求的是第項的式子:
記
二項式定理展開:
整理得:
再記
那麼
注意到可以預處理出來,可以預處理出來,而就可以得到.
注意!
程式碼
#include <iostream>
#include <algorithm>
#include <cstring>
#define pr(x) std::cout << #x << ':' << x << std::endl
#define rep(i,a,b) for(int i = a;i <= b;++i)
typedef long long LL;
const int N = 100010;
const LL P = 1e9+7;
int T,n,k;
char s[N];
long long S[101][N],SS[101][N];
long long C[110][110];
void init() {
C[0][0] = 1;
for(int i = 1;i <= 100;++i) {
C[i][0] = 1;
for(int j = 1;j <= i;++j) {
C[i][j] = (C[i-1][j-1] + C[i-1][j]) % P;
}
}
}
int main() {
std::ios::sync_with_stdio(false);
init();
std::cin >> T;
while(T--) {
std::cin >> n >> k;
std::cin >> s;
for(int i = 0;i <= n;++i) S[0][i] = 1;
for(int i = 1;i <= n;++i) S[1][i] = (s[i-1]-'0') + S[1][i-1] ;
for(int i = 2;i <= k;++i)
for(int j = 1;j <= n;++j)
S[i][j] = S[1][j] * S[i-1][j] % P;
SS[0][0] = 1;
for(int i = 0;i <= k;++i) {
for(int j = 1;j <= n;++j)
SS[i][j] = (SS[i][j-1] + S[i][j])% P;
}
for(int i = 1;i <= n;++i) {
long long ans = 0;
for(int j = 0;j <= k;++j) {
long long res = C[k][j]*S[j][i]%P*SS[k-j][i-1]%P;
if((k-j)%2==0) ans = (ans + res) % P;
else ans = (ans - res + P) % P;
}
if(i != 1) std::cout << " ";
std::cout << ans;
}
std::cout << std::endl;
}
return 0;
}