zoukankan      html  css  js  c++  java
  • POJ3150:Cellular Automaton

    题意看不懂加题目想不通,很菜。

    n<=500个数围城环,每次操作对每个数Ai把与i在环上相距不超过d<n/2(包括Ai)的数加起来取模m<=1e6,求K<=1e7次操作后的环。

    存在递推关系,构造矩阵吧!比如样例一很丑。

    于是矩阵快速幂,n*n*n*logK,很慢。

    这个矩阵比较奇怪,每一行都是上一行右移一位,而且每一行和每一列长得一样。也就是说我们只保存第一行就能知道整个矩阵长什么样。

    而我们的时间主要浪费在a的相乘上,所以a只维护一行,计算答案时把a还原,更新一行的“a”时亦然,具体见代码。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 #include<math.h>
     5 //#include<iostream>
     6 using namespace std;
     7 
     8 int n,mod,d,K;
     9 #define maxn 511
    10 int a[maxn],b[maxn];
    11 void mul(int *a,int *b,int *ans)
    12 {
    13     int t[maxn];
    14     memset(t,0,sizeof(t));
    15     for (int i=1;i<=n;i++)
    16         for (int j=1;j<=n;j++)
    17             t[i]=(t[i]+1ll*a[j-i+1+(j-i>=0?0:n)]*b[j]%mod)%mod;
    18     for (int i=1;i<=n;i++) ans[i]=t[i];
    19 }
    20 int main()
    21 {
    22     scanf("%d%d%d%d",&n,&mod,&d,&K);
    23     for (int i=1;i<=n;i++) scanf("%d",&b[i]);
    24     memset(a,0,sizeof(a));
    25     for (int i=1;i<=d+1;i++) a[i]=1;
    26     for (int i=n;i>n-d;i--) a[i]=1;
    27     while (K)
    28     {
    29         if (K&1) mul(a,b,b);
    30         mul(a,a,a);
    31         K>>=1;
    32     }
    33     for (int i=1;i<=n;i++) printf("%d ",b[i]);
    34     return 0;
    35 }
    View Code
  • 相关阅读:
    iView
    JS
    JS
    JS
    Java
    Java
    Java
    Java
    Java
    Java
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7445402.html
Copyright © 2011-2022 走看看