考虑一个含有 N 个细胞的一维细胞自动机。细胞从 0 到 N-1 标号。每个细胞有一个被表示成一个小于 M 的非负整数的状态。细胞的状态会在每个整数时刻发生骤变。我们定义 S(i,t) 表示第 i 个细胞在时刻 t 的状态。在时刻 t+1 的状态被表示为 S(i,t+1)=(A×S(i-1,t)+B×S(i,t)+C×S(i+1,t) ) mod M ,其中 A,B,C 是给定的非负整数。对于 i<0 或 N≤i ,我们定义 S(i,t)=0 。给定一个自动机的定义和其细胞在时刻 0 的初始状态,你的任务是计算时刻 T 时每个细胞的状态。
输入包含多组测试数据。每组数据的第一行包含六个整数 N,M,A,B,C,T ,满足 0<N≤50,0<M≤1000,0≤A,B,C<M,0≤T≤〖10〗^9 。第二行包含 N 个小于 M 的非负整数,依次表示每个细胞在时刻 0 的状态。输入以六个零作为结束。
对于每组数据,输出N个小于M的非负整数,每两个相邻的数字之间用一个空格隔开,表示每个细胞在时刻T的状态。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int n,m,A,B,C,T;
struct M
{
int a[60][60];
int * operator [] (int b) {return a[b];}
M() {memset(a,0,sizeof(a));}
M operator * (M b)
{
M c;
int i,j,k;
for(i=0;i<n;i++) for(j=0;j<n;j++) for(k=0;k<n;k++) c[i][j]=(c[i][j]+a[i][k]*b[k][j])%m;
return c;
}
}tr,ans;
void pm(int y)
{
while(y)
{
if(y&1) ans=ans*tr;
tr=tr*tr,y>>=1;
}
}
int main()
{
while(1)
{
scanf("%d%d%d%d%d%d",&n,&m,&A,&B,&C,&T);
if(!m) return 0;
int i;
memset(tr.a,0,sizeof(tr.a)),memset(ans.a,0,sizeof(ans.a));
for(i=0;i<n;i++)
{
scanf("%d",&ans[0][i]);
if(i) tr[i-1][i]=A;
tr[i][i]=B;
if(i<n-1) tr[i+1][i]=C;
}
pm(T);
for(i=0;i<n;i++) printf("%d%c",ans[0][i],i==n-1?‘\n‘:‘ ‘);
}
}