Cellular Automaton
Time limit:12000 Ms |
|
Memory limit:65536 K |
Total submissions:3048 |
|
Accepted:1227 |
Case time limit:2000 ms |
Description
ACellular AutomatonIs 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. theOrder of the cellular automatonIs the number of cells it contains. Cells of the automaton of orderNAre numbered from 1N.
TheOrder of the cellIs the number of different values it may contain. Usually, values of a cell of orderMAre considered to be integer numbers from 0M? 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 orderNWith cells of orderM. We will denote such kind of cellular automatonN, m-Automaton.
A distance between cellsIAndJInN,M-Automaton is defined as Min (|I?J|,N? |I?J|).D-environment of a cellIs the set of cells at a distance not greaterD.
On eachD-stepValues of all cells are simultaneously replaced by new values. The new value of CellIAfterD-Step is computed as a sum of values of cells belonging toD-Enviroment of the cellIModuloM.
The following picture shows 1-step of the 5, 3-automaton.
The problem is to calculate the state ofN,M-Automaton afterK d-Steps.
Input
The first line of the input file contains four integer numbersN,M,D, AndK(1 ≤N≤ 500, 1 ≤M≤ 1 000 000, 0 ≤D<N? 2, 1 ≤K≤ 10 000 000). The second line contains N integer numbers from 0M? 1-initial values of the automaton's cells.
Output
Output the values ofN,M-Automaton's cells afterK d-Steps.
Sample Input
sample input #15 3 1 11 2 2 1 2sample input #25 3 1 101 2 2 1 2
Sample output
sample output #12 2 2 2 1sample output #22 0 0 2 2
Source
Northeastern Europe 2006.
There is a ring with a length of N. Each node has a number on it. Each node on the ring can be updated so that the value of the node changes to the sum of all nodes whose distance from the node on the ring is less than or equal to D, and then Modulo M. Each operation updates all vertices on the ring and asks the number of each point on the ring after K operations.
Solution: first, we can think of using matrices instead of operations. (For the first group of questions) First, matrix A = 1 2 2 1 2
B =
1 1 0 0 1
1 1 1 0 0
0 1 1 1 0
0 0 1 1 1
1 0 0 1 1 then it can be solved through the matrix Rapid power. In this case, the complexity is (logk * n ^ 3), and T.
In fact, this matrix is regular. B ^ 1 =
[1, 1, 0, 0, 1]
[1, 1, 1, 0, 0]
[0, 1, 1, 1, 0]
[0, 0, 1, 1, 1]
[1, 0, 0, 1, 1]
B ^ 2 =
[3, 2, 1, 1, 2]
[2, 3, 2, 1, 1]
[1, 2, 3, 2, 1]
[1, 1, 2, 3, 2]
[2, 1, 1, 2, 3]
B ^ 3 =
[7, 6, 4, 4, 6]
[6, 7, 6, 4, 4]
[4, 6, 7, 6, 4]
[4, 4, 6, 7, 6]
[6, 4, 4, 6, 7]
B ^ 4 =
[19, 17, 14, 14, 17]
[17, 19, 17, 14, 14]
[14, 17, 19, 17, 14]
[14, 14, 17, 19, 17]
[17, 14, 14, 17, 19]
We can see that as long as the first number in row I of the matrix is moved to the end, it becomes the row I + 1 of the matrix. Therefore, we only need to know a row of the Matrix to push other rows. Therefore, the complexity of N ^ 3 is n ^ 2.
Code:
/*ID: [email protected]PROG:LANG: C++*/#include<map>#include<set>#include<queue>#include<stack>#include<cmath>#include<cstdio>#include<vector>#include<string>#include<fstream>#include<cstring>#include<ctype.h>#include<iostream>#include<algorithm>#define INF (1<<30)#define PI acos(-1.0)#define mem(a, b) memset(a, b, sizeof(a))#define For(i, n) for (int i = 0; i < n; i++)typedef long long ll;using namespace std;const int maxn = 505;const int maxm = 505;int mod, n, k, d;void Matrix_pow(int a[], int b[]) { ll c[505] = {0}; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) c[i] += ((ll)a[j] * b[(i + j) % n]) % mod; c[i] %= mod; } for (int i = 0; i < n; i++) b[i] = c[i];}int a[505], b[505];int main () { while(scanf("%d%d%d%d", &n, &mod, &d, &k) != EOF) { for (int i = 0; i < n; i++) scanf("%d", b + i); memset(a, 0, sizeof(a)); a[0] = 1; for (int i = 1; i <= d; i++) a[i] = a[n - i] = 1; while(k) { if (k & 1) Matrix_pow(a, b); k >>= 1; Matrix_pow(a, a); } for (int i = 0; i < n; i++) printf("%d%c", b[i], " \n"[i == n - 1]); } return 0;}
Reference: http://www.cppblog.com/varg-vikernes/archive/2011/02/08/139804.html