• POJ3150—Cellular Automaton(循环矩阵)


    题目链接:http://poj.org/problem?id=3150

    题目意思:有n个数围成一个环,现在有一种变换,将所有距离第i(1<=i<=n)个数小于等于d的数加起来,对m取余,现在要求将所有的数都变换k次,得到的n个数的值。

    思路:构造一个循环矩阵,以下这个矩阵是以样例1为例的循环矩阵。

    1 1 0 0 1
    1 1 1 0 0
    0 1 1 1 0
    0 0 1 1 1
    1 0 0 1 1

    我们发现n尽然达到了500,复杂度是n^3logk,过不了,我们发现这个矩阵长得很奇葩,每一行都是上一行后移一位得到,所以我们每个矩阵可以n^2算出一行,然后通过平移得到全部的矩阵。从而把n^3的矩阵乘法变成n^2,复杂度是n^2logk,就可以AC了,其他没有什么奇怪的操作。第一道循环矩阵题,算是涨姿势了,循环矩阵乘法模板记住了。

    代码:

     1 //Author: xiaowuga
     2 #include<iostream>
     3 #include<cstring>
     4 #define maxx INT_MAX
     5 #define minn INT_MIN
     6 #define inf 0x3f3f3f3f
     7 #define N  505
     8 using namespace std;
     9 long long MOD;
    10 typedef long long ll;
    11 long long  n,size;//第n项,矩阵大小
    12  long long f[550];
    13 struct Matrix{
    14     long long mat[N][N];
    15     void clear(){
    16         memset(mat,0,sizeof(mat));
    17     }
    18     Matrix operator * (const Matrix & m) const{
    19         Matrix tmp;
    20         tmp.clear();
    21         for(int i=0;i<size;i++){
    22             for(int j=0;j<size;j++){
    23                 tmp.mat[0][i]+=mat[0][j]*m.mat[j][i]%MOD;
    24             }
    25             tmp.mat[0][i]%=MOD;
    26         }
    27         for(int i=1;i<size;i++){
    28             for(int j=0;j<size;j++)
    29                 tmp.mat[i][j]=tmp.mat[i-1][(j+size-1)%size];
    30         }
    31         return tmp;
    32     }
    33 }M,ANS;
    34 Matrix ans;
    35 void POW(Matrix m,ll k){
    36     memset(ans.mat,0,sizeof(ans.mat));
    37     for(int i=0;i<size;i++) ans.mat[i][i]=1;
    38     while(k){
    39         if(k&1) ans=ans*m;
    40         k/=2;
    41         m=m*m;
    42     }
    43      long long sum;
    44         for(int i=0;i<size;i++){
    45             sum=0;
    46             for(int j=0;j<size;j++){
    47                 sum+=ans.mat[i][j]*f[j]%MOD;
    48             }
    49             if(i==0) cout<<sum%MOD;
    50             else cout<<" "<<sum%MOD;
    51         }
    52         cout<<endl;
    53 }
    54 int main() {
    55     ios::sync_with_stdio(false);cin.tie(0);
    56     long long d;
    57     while(cin>>size>>MOD>>d>>n){
    58         M.clear();
    59         for(int i=0;i<size;i++) cin>>f[i];
    60         for(int i=0;i<size;i++){
    61             M.mat[i][i]=1;
    62             for(int j=1;j<=d;j++){
    63                 M.mat[i][(i+j+size)%size]=1;
    64                 M.mat[i][(i-j+size)%size]=1;
    65             }
    66         }
    67         for(int i=0;i<size;i++){
    68             for(int j=0;j<size;j++) cout<<M.mat[i][j]<<' ';
    69             cout<<endl;
    70         }
    71         POW(M,n);
    72     }
    73     return 0;
    74 }
    View Code
  • 相关阅读:
    2020-08-11 题目题解
    N皇后问题
    逆序对(模板)
    归并选择(模板)
    快速选择(模板)
    快速排序(模板)
    vuecli4+elementui实现面包屑
    vue-路由导航(守卫)那些事
    vue-vant中ImagePreview 图片预览正确的打开方式
    Selenium 对表格table处理
  • 原文地址:https://www.cnblogs.com/xiaowuga/p/7355354.html
Copyright © 2020-2023  润新知