UVa 1386 - Cellular Automaton

来源:互联网 发布:局域网网络监视 编辑:程序博客网 时间:2024/06/09 23:00


利用循环矩阵相乘仍是循环矩阵的性质,将复杂度从n^3*log(k)降到n^2*log(k)。


而且a[500][500]做传参太大, 程序会直接崩掉。


#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>typedef long long LL;typedef unsigned long long LLU;using namespace std;const int N=500+1;int MOD, n, k, d;LL res[N], init[N];void Mult(LL a[], LL b[]){    LL c[N];    for(int i=0; i<n; i++)    {        c[i]=0;        for(int j=0; j<n; j++)            c[i]=(c[i]+a[j]*b[(i-j+n)%n])%MOD;    }    memcpy(a, c, sizeof(c));}void Pow(int b){    memset(res, 0, sizeof(res));    memset(init, 0, sizeof(init));    for(int i=0; i<=d; i++)        init[i]=init[(n-i)%n]=1;    res[0]=1;    while(b)    {        if(b&1)Mult(res, init);        Mult(init, init);        b>>=1;    }}int main(){    while(~scanf("%d%d%d%d", &n, &MOD, &d, &k))    {        Pow(k);        LL a[N], ans[N]={0};        for(int i=0; i<n; i++)            scanf("%d", &a[i]);        for(int i=0; i<n; i++)            for(int j=0; j<n; j++)                ans[i]=(ans[i]+a[j]*res[(i+n-j)%n])%MOD;        printf("%lld", ans[0]);        for(int i=1; i<n; i++)            printf(" %lld", ans[i]);        printf("\n");    }    return 0;}


0 0
原创粉丝点击