zoukankan      html  css  js  c++  java
  • UVALive 3704 细胞自动机 矩阵快速幂

    是时候要做做数学类的题目了

    这属于比较简单的矩阵快速幂了,因为有个已知的矩阵循环的结论,所以为了节约时空,只需要保留一行即可,这个稍微有点难写,也不是难写,主要是注意细节。其他的矩阵快速幂一下即可

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 505
    #define ll long long
    using namespace std;
    struct Mat
    {
        ll mat[1][N];
    }E,Z,O;
    ll n,m,d,k;
    void init()
    {
        memset(E.mat,0,sizeof E.mat);
        for (int i=0;i<n;i++)
            E.mat[i][i]=1;
        memset(O.mat,0,sizeof O.mat);
        int tmp=0;
        for (int j=-d;tmp<2*d+1;j++,tmp++){
            if (j<0) j+=n;
            if (j>=n) j%=n;
            O.mat[0][j]=1;
        }
    //    cout<<"!!!"<<endl;
    //    for (int i=0;i<n;i++)
    //        cout<<O.mat[0][i]<<" ";
    //    cout<<endl;
    }
    Mat operator *(Mat a,Mat b)
    {
        Mat c=Z;
        int i,j;
        for (i=0;i<n;i++){
            int cur=n-i;
            for (j=0;j<n;j++){ 
              if (cur>=n) cur%=n;//因为是循环矩阵,由第一行即可推得其他列的情况
              c.mat[0][i]+=a.mat[0][j]*b.mat[0][cur];
              cur++;
              if (c.mat[0][i]>=m) c.mat[0][i]%=m;
            }
        }
        return c;
    }
    Mat operator ^(Mat a,ll x)
    {
        Mat c=E;
        for (;x;x>>=1){
            if (x&1){
                c=c*a;
            }
            a=a*a;
        }
        return c;
    }
    ll A[N],B[N];
    int main()
    {
        memset(Z.mat,0,sizeof Z.mat);
        while (scanf("%lld%lld%lld%lld",&n,&m,&d,&k)!=EOF)
        {
            init();
            Mat ans=O^k;
    //        for (int i=0;i<n;i++)
    //            cout<<ans.mat[0][i]<<" ~ ";
    //        cout<<endl;
            for (int i=0;i<n;i++)
                scanf("%lld",&A[i]);
            for (int i=0;i<n;i++){
                int cur=n-i;
                B[i]=0;
                for (int j=0;j<n;j++){
                    if (cur>=n) cur%=n;
                    B[i]+=ans.mat[0][cur]*A[j];
                    cur++;
                    if (B[i]>=m) B[i]%=m;
                }
            }
            printf("%lld",B[0]);
            for (int i=1;i<n;i++)
                printf(" %lld",B[i]);
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    C#
    Excel 中大量图片如何快速导出? 转载自:http://www.zhihu.com/question/20800948
    IE的F12开发人员工具不显示 转载自:http://blog.csdn.net/longyulu/article/details/8749705
    firefox ie 比较 relative path
    fiddler save files
    selenium3加载浏览器
    Linux安装PHP
    客户端级别的渲染分析工具 dynaTrace
    前端性能分析:分析百度和sogou
    Linux vi的基本操作
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3687483.html
Copyright © 2011-2022 走看看