uva 1386

来源:互联网 发布:免费的电子书软件 编辑:程序博客网 时间:2024/05/29 12:52

题目很恶心,读不懂,百度的题意。

题目大意:一个细胞自动机,有n个格子,每个格子的取值为0~m-1。给定距离d,

每次操作后每个格子的值将变为到它距离不超过d的所有格子在操作之前的值之和除以m的余数。

普通的矩阵乘法会超时,然后就看到一个黑科技,循环矩阵

循环矩阵乘法那里细节方面感觉还是有点不大清楚

//  Created by Chenhongwei on 2016-05-01 Sunday 19:03//  Copyright (c) 2016 Chenhongwei. All rights reserved.#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <climits>#include <queue>#include <cmath>#include <map>#include <set>#include <stack>#include <vector>#include <sstream>#include <algorithm>#define root 1,n,1#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;const int inf=1e9;const int mod=1e9+7;const int maxn=1e5+100;typedef long long ll;typedef unsigned long long ull;ll n,m,d,k;ll a[550];ll tmp[550],s[550];void mul(ll a[],ll b[]){ll c[550];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])%m;}memcpy(a,c,sizeof c);}void fast_pow(){memset(s,0,sizeof s);memset(tmp,0,sizeof tmp);s[0]=1;for(int i=0;i<=d;i++)tmp[i]=tmp[n-i]=1;while(k){if(k&1)mul(s,tmp);mul(tmp,tmp);k>>=1;}}int main(){//ios::sync_with_stdio(false);    // freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);while(scanf("%lld%lld%lld%lld",&n,&m,&d,&k)!=EOF){ll ans[550];for(int i=0;i<n;i++)scanf("%lld",&a[i]);fast_pow();for(int i=0;i<n;i++){ans[i]=0;for(int j=0;j<n;j++)ans[i]=(ans[i]+a[j]*s[(i-j+n)%n])%m;}for(int i=0;i<n;i++)printf("%lld%c",ans[i],i==n-1?'\n':' ');}return 0;}


0 0