A cellular automaton is a collection of cells on a grid of specified shape that evolves through a number of discrete time steps according to a set of rules that describe the new state of a cell based on the states of neighboring cells. The order of the cellular automaton is the number of cells it contains. Cells of the automaton of order n are numbered from 1 to n.
The order of the cell is the number of different values it may contain. Usually, values of a cell of order m are considered to be integer numbers from 0 to m - 1.
One of the most fundamental properties of a cellular automaton is the type of grid on which it is computed. In this problem we examine the special kind of cellular automaton -- circular cellular automaton of order n with cells of order m. We will denote such kind of cellular automaton as n, m - automaton.
A distance between cells i and j in n, m-automaton is defined as min(| i - j|, n - | i - j|). A d-environment of a cell is the set of cells at a distance not greater than d.
On each d-step values of all cells are simultaneously replaced by new values. The new value of cell i after d-step is computed as a sum of values of cells belonging to the d-enviroment of the cell i modulo m.
The following picture shows 1-step of the 5,3-automaton.
Input
The input file contains several test cases, each of them consists of two lines, as described below.
The first line of the input contains four integer numbers n,
m, d, and
k (1n
500,
1
m
1000000,
0
d <
, 1
k
10000000).
The second line contains n integer numbers 2 from 0 to
m - 1 -- initial values of the automaton's cells.
Output
For each test case, write to the output, on a line by itself,the values of the
n, m
Sample Input
5 3 1 1 1 2 2 1 2 5 3 1 10 1 2 2 1 2
Sample Output
2 2 2 2 1 2 0 0 2 2
一个圆环,每次操作把这个数变成附近d个数的和,输出经过K次操作的情况。
构造一个矩阵A,例如当d=1时有
1 1 0 ... 0 1
1 1 1 0 ... 0
0 1 1 1 0 ...
... 0 1 1 1 0
1 ... 0 1 1 1
1 0 ... 0 1 1
是一个每次右移的循环矩阵。
这样答案vk=A^k*v0,如果直接矩阵快速幂,时间复杂度O(n^3 logk),有点大。因为循环矩阵的乘积仍然是循环矩阵,所以可以只储存第一行,计算的时候也计算第一行。其他行可以根据第一行推出来。矩阵乘法时间复杂度降为O(n^2),总时间降为O(n^2logk)。
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<vector>
#define INF 0x3f3f3f3f
#define MAXN 510
#define MAXM 110
#define MOD 1000000007
#define MAXNODE 4*MAXN
#define eps 1e-9
using namespace std;
typedef long long LL;
typedef vector<LL> Mat;
int N,M,D,K;
Mat operator *(Mat &a,Mat &b){
Mat ret(MAXN);
for(int i=0;i<N;i++)
for(int j=0;j<N;j++) ret[i]=(ret[i]+a[j]*b[(j-i+N)%N])%M;
return ret;
}
Mat operator ^(Mat &x,LL n){
Mat ret(MAXN),t=x;
ret[0]=1;
while(n){
if(n&1) ret=ret*t;
t=t*t;
n>>=1;
}
return ret;
}
int main(){
freopen("in.txt","r",stdin);
while(scanf("%d%d%d%d",&N,&M,&D,&K)!=EOF){
Mat mat(MAXN),ans(MAXN),a(MAXN);
for(int i=0;i<=D;i++) mat[i]=mat[(N-i)%N]=1;
mat=mat^K;
for(int i=0;i<N;i++) scanf("%lld",&a[i]);
for(int i=0;i<N;i++)
for(int j=0;j<N;j++) ans[i]=(ans[i]+mat[(j-i+N)%N]*a[j])%M;
for(int i=0;i<N-1;i++) printf("%lld ",ans[i]);
printf("%d\n",ans[N-1]);
}
return 0;
}