友矩阵为循环矩阵,储存和计算矩阵乘法时只算出第一行
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <cctype>
#include <string>
#include <cmath>
#include <algorithm>
#include <queue>
#include <set>
#include <vector>
#include <map>
#define PR pair<int,int>
#define MP make_pair
#define fi first
#define se second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define sqr(x) ((x)*(x))
#define ll long long
#define ull unsigned __int64
const ll INF = 1e18;
const int inf=0x3f3f3f3f;
const int M=444444;
const int N=505;
const int MOD=1000000007;
const double eps=1e-10;
const double pi=3.1415926536;
using namespace std;
int n,m,d,c;
struct MAT
{
ll mat[N];
friend MAT operator*(MAT &x,MAT &y);
friend MAT operator^(MAT x,int y);
};
typedef struct MAT Mat;
Mat operator*(Mat &x,Mat &y)
{
Mat ans;
for(int j=0;j<n;j++)
{
ans.mat[j]=0;
for(int k=j,cnt=0;cnt<n;k=(k+1)%n,cnt++)
{
ans.mat[j]=(ans.mat[j]+y.mat[cnt]%m*x.mat[k]%m)%m;
}
}
return ans;
}
Mat operator^(Mat x,int y)
{
y--;
Mat init=x;
while(y)
{
if(y&1) init=init*x;
x=x*x;
y>>=1;
}
return init;
}
Mat a,b;
int main()
{
while(~scanf("%d%d%d%d",&n,&m,&d,&c))
{
for(int i=0;i<n;i++)
scanf("%lld",&a.mat[i]);
memset(b.mat,0,sizeof(b.mat));
for(int i=0;i<d+1;i++)
b.mat[i]=1;
for(int i=n-1;i>=n-d;i--)
b.mat[i]=1;
b=b^c;
for(int i=0;i<n;i++)
{
ll ans=0;
for(int j=(n-i)%n,cnt=0;cnt<n;j=(j+1)%n,cnt++)
ans+=a.mat[cnt]%m*b.mat[j]%m;
printf("%lld",ans%m);
if(i==n-1) puts("");
else printf(" ");
}
}
}