1 /*LA3704:
2 细胞自动机(矩阵):
3 关键是辨别和变换矩阵的构造
4 变换矩阵Mat:
5 第i列的构造,for(j=i-d;j<=i+d;j++) {k=(j+n)%n,M.mat[k][i]=1;},其余为零
6 取模的作用比较巧妙
7 */
8 #include<iostream>
9 #include<stdio.h>
10 #include<string.h>
11 #include<algorithm>
12 #include<stdlib.h>
13 #include<math.h>
14 #include<queue>
15 #include<vector>
16 #include<map>
17 #define ULL unsigned long long
18 #define LL long long
19 #define Max_size 17
20 #define size n
21 #define MOD m
22 using namespace std;
23
24 int n,m,d,k;
25
26 struct Mat
27 {
28 LL mat[Max_size][Max_size];
29
30 };
31 Mat operator*(Mat a,Mat b)
32 {
33 Mat c;
34 memset(c.mat,0,sizeof(c.mat));
35 for (int i=0;i<size;i++)
36 for (int j=0;j<size;j++)
37 for (int k=0;k<size;k++)
38 if (a.mat[i][k] && b.mat[k][j])
39 c.mat[i][j]=(c.mat[i][j]+a.mat[i][k]*b.mat[k][j])%MOD;
40 return c;
41 }
42 Mat operator+(Mat a,Mat b)
43 {
44 Mat c;
45 memset(c.mat,0,sizeof(c.mat));
46 for (int i=0;i<size;i++)
47 for (int j=0;j<size;j++)
48 c.mat[i][j]=(a.mat[i][j]+b.mat[i][j])%MOD;
49 return c;
50 }
51 Mat E;
52
53 void builtE()
54 {
55 memset(E.mat,0,sizeof(E.mat));
56 for (int i=0;i<Max_size;i++)
57 {
58 E.mat[i][i]=1;
59 }
60 }
61 Mat operator^(Mat A,int x)
62 {
63 Mat c;
64 builtE();
65 c=E;
66 for ( ; x; x>>=1)
67 {
68 if ( x & 1)
69 c = c * A;
70 A = A * A;
71 }
72 return c;
73 }
74 Mat K,F;
75
76 int main()
77 {
78 while(cin>>n>>m>>d>>k)
79 {
80 memset(K.mat,0,sizeof(K.mat));
81 memset(F.mat,0,sizeof(F.mat));
82 for(int i=0;i<n;i++) cin>>F.mat[0][i];
83
84 for(int i=0;i<n;i++)
85 for(int j=i-d;j<=i+d;j++)
86 {
87 int p=(j+n)%n;K.mat[p][i]=1;
88 }
89
90 K=K^k;
91 F=F*K;
92 for(int i=0;i<n;i++) if (i<n-1) cout<<F.mat[0][i]<<" ";else cout<<F.mat[0][i]<<endl;
93
94 }
95 return 0;
96 }