uva1386 - Cellular Automaton 循环矩阵

本文介绍了一种特殊的圆环细胞自动机模型及其模拟过程。该模型通过将每个单元格的状态更新为其周围指定距离内单元格状态之和的模运算来实现演化。文章详细解释了如何构建并利用循环矩阵进行高效计算,以快速模拟经过多次迭代后的自动机状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 (1$ \le$n$ \le$500, 1$ \le$m$ \le$1000000, 0$ \le$d < $ {n \over 2}$, 1$ \le$k$ \le$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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值