题目 https://vjudge.net/problem/UVALive-3704
构造出来矩阵后,发现这是一个循环矩阵,从第二行开始每一行都是上一行向右,所以只需要保留第一行数据,使时间复杂度边为(O^2log k)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=500+5;
int mod;
struct Matrix{
int n;
ll M[maxn];
Matrix(int n):n(n){memset((M),0,sizeof(M));}
Matrix operator *(const Matrix & rhs) const{
Matrix ret(n);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++)
ret.M[i]+=M[j]*rhs.M[(j-i+n)%n];
ret.M[i]%=mod;
}
return ret;
}
Matrix operator *=(const Matrix &rhs) {
return *this=*this*rhs;
}
};
Matrix pow(Matrix x,int k){
if(--k==0) return x;
Matrix ret=x;
while(k>0){
if(k&1) ret*=x;
k>>=1;
x*=x;
}
return ret;
}
int main(){
int n,d,k;
while(~scanf("%d %d %d %d",&n,&mod,&d,&k)){
Matrix A(n),F(n);
for(int i=0;i<n;i++) scanf("%lld",&F.M[i]);
for(int i=0;i<n;i++) if(min(i,n-i)<=d) A.M[i]=1;
A=pow(A,k);
F=F*A;
printf("%lld",F.M[0]);
for(int i=1;i<n;i++) printf(" %lld",F.M[i]);
printf("\n");
}
}