zoukankan      html  css  js  c++  java
  • UVA 1386 Cellular Automaton

    矩阵快速幂。

    样例是这样构造矩阵的:

    矩阵很好构造,但是500*500*500*logk的复杂度显然是无法通过这题的。

    其实本题构造出来的矩阵是一个循环矩阵,只需直到第一行或者第一列,即可直到整个矩阵是怎么样的。

    所以,中间计算的时候,需要直到第一行是什么即可,即1*n的矩阵乘n*n的矩阵。时间复杂度o(n*n*logk)

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<algorithm>
    using namespace std;
    
    const int maxn=500+10;
    int n,d,k;
    long long mod;
    long long z[maxn],a[maxn];
    long long y[maxn],x[maxn];
    long long tmp[maxn][maxn];
    long long r[maxn];
    
    void init()
    {
        memset(y,0,sizeof y);
        y[1]=1;
        memset(x,0,sizeof x);
        x[1]=1;
        for(int i=2; i<=1+d; i++) x[i]=1;
        for(int i=n; i>=n-d+1; i--)x[i]=1;
    }
    
    int main()
    {
        while(~scanf("%d%lld%d%d",&n,&mod,&d,&k))
        {
            for(int i=1; i<=n; i++) scanf("%lld",&z[i]);
            init();
            while(k)
            {
                for(int i=1; i<=n; i++)
                {
                    int tot=1;
                    for(int j=i; j<=n; j++) tmp[i][j]=x[tot++];
                    for(int j=1; j<=i-1; j++) tmp[i][j]=x[tot++];
                }
    
                if(k%2==1)
                {
                    for(int j=1; j<=n; j++)
                    {
                        long long sum=0;
                        for(int t=1; t<=n; t++) sum=(sum+(y[t]*tmp[j][t])%mod)%mod;
                        r[j]=sum;
                    }
    
                    for(int j=1; j<=n; j++) y[j]=r[j];
    
                    k--;
                }
                else if(k%2==0)
                {
                    for(int j=1; j<=n; j++)
                    {
                        long long sum=0;
                        for(int t=1; t<=n; t++) sum=(sum+(x[t]*tmp[j][t])%mod)%mod;
                        r[j]=sum;
                    }
                    for(int j=1; j<=n; j++) x[j]=r[j];
    
                    k=k/2;
                }
            }
    
            for(int i=1; i<=n; i++)
            {
                int tot=1;
                for(int j=i; j<=n; j++) tmp[i][j]=y[tot++];
                for(int j=1; j<=i-1; j++) tmp[i][j]=y[tot++];
            }
    
            for(int j=1; j<=n; j++)
            {
                long long sum=0;
                for(int t=1; t<=n; t++) sum=(sum+(z[t]*tmp[j][t])%mod)%mod;
                r[j]=sum;
            }
    
            for(int j=1; j<=n; j++)
            {
                printf("%d",r[j]);
                if(j<n) printf(" ");
                else printf("
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    mysql mysqldump 本地数据库导入本地数据库的命令
    window mysql5.7 zip 安装
    MySQL存储过程详解 mysql 存储过程
    spring batch 读取多个文件数据导入数据库
    spring batch 以游标的方式 数据库读取数据 然后写入目标数据库
    不同浏览器上中文文件名的下载乱码问题
    spring mvc 文件下载 get请求解决中文乱码问题
    SpringMVC上传文件的三种方式
    NSPort
    iOS NSRunloop
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5258210.html
Copyright © 2011-2022 走看看