题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=15129
【思路】
矩阵乘法-循环矩阵
题目中的转移矩阵是一个循环矩阵,循环矩阵的乘积依旧是循环矩阵,这样保留矩阵第一行进行快速幂乘法即可。
【代码】
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std; typedef long long LL;
const int N = +; int m,n,d,k; void mul(LL a[],LL b[]) {
LL c[N];
for(int i=;i<n;i++) {
c[i]=;
for(int j=;j<n;j++)
c[i]=(c[i]+a[j]*b[(i-j+n)%n])%m;
}
memcpy(a,c,sizeof(c));
}
LL ans[N],tmp[N],A[N]; void pow(int p) {
memset(ans,,sizeof(ans));
memset(tmp,,sizeof(tmp));
for(int i=-d;i<d+;i++) {
tmp[(i+n)%n]=;
}
ans[]=;
while(p) {
if(p&) mul(ans,tmp);
mul(tmp,tmp);
p>>=;
}
} int main() {
while(scanf("%d%d%d%d",&n,&m,&d,&k)==) {
pow(k);
for(int i=;i<n;i++) scanf("%d",&A[i]);
mul(ans,A);
printf("%lld",ans[]);
for(int i=;i<n;i++) printf(" %lld",ans[i]);
putchar('\n');
}
return ;
}