zoukankan      html  css  js  c++  java
  • hdu5015 矩阵快速幂233(好题)

    题意:
          给你一个(n+1)*(m+1)的矩阵mat,然后给你mat[0][1] = 233 ,mat[0][2] = 2333,mat[0][3] = 23333...,然后输入mat[1][0] ,mat[2][0] ,mat[3][0]....然后给了矩阵中的其他数值是mat[i][j] = mat[i-1][j] + mat[i][j-1],最后让你输出mat[n][m]。

    思路:
       其中n <= 10 m <= 10^9 ,直接暴力果断超时,这个题目我们要仔细观察,n <= 10这个很重要,太大的话就不好弄了。这个题目我们可以用矩阵快速幂去做,构造一个n+2的矩阵


      a[1] a[2] a[n] 233 3       1  1  1  0 0      a[1] a[2] a[n] 2333 3 
                             *   0  1  1  0 0   =
                                 0  0  1  0 0
                                 1  1  1 10 0
                                 0  0  0  1 1

    提示下,矩阵这么建的原因是比如当前的a[3] = 上一步的 a[1] + a[2] + a[3] + 233..ok


    #include<stdio.h>
    #include<string.h>
    
    #define MOD 10000007
    
    typedef struct
    {
       __int64 mat[15][15];
    }A;
    
    A mat_mat(A a ,A b ,int n)
    {
       A c;
       memset(c.mat ,0 ,sizeof(c.mat));
       for(int k = 1 ;k <= n ;k ++)
       for(int i = 1 ;i <= n ;i ++)
       if(a.mat[i][k])
       for(int j = 1 ;j <= n ;j ++)
       c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % MOD;
       return c;
    }
    
    A quick_mat(A a ,int b ,int n)
    {
       A c;
       memset(c.mat ,0 ,sizeof(c.mat));
       for(int i = 1 ;i <= n ;i ++)
       c.mat[i][i] = 1;
       while(b)
       {
          if(b&1) c = mat_mat(c ,a ,n);
          a = mat_mat(a ,a ,n);
          b >>= 1;
       }
       return c;
    }
    
    int main ()
    {
       int i ,j ,n ,m;
       A GZ;
       int num[15];
       while(~scanf("%d %d" ,&n ,&m))
       {
          for(i = 1 ;i <= n ;i ++)
          scanf("%d" ,&num[i]);
          memset(GZ.mat ,0 ,sizeof(GZ.mat));
          for(j = 1 ;j <= n ;j ++)
          {  
             for(i = 1 ;i <= j ;i ++) 
             GZ.mat[i][j] = 1;
             GZ.mat[n+1][j] = 1;
          }
          GZ.mat[n+1][n+1] = 10;
          GZ.mat[n+2][n+1] = GZ.mat[n+2][n+2] = 1;
             
          A now = quick_mat(GZ ,m ,n + 2);
          
          __int64 Ans = 0;
          for(i = 1 ;i <= n ;i ++)
          Ans = (Ans + num[i] * now.mat[i][n]) % MOD;
          Ans = (Ans + 233 * now.mat[n+1][n] + 3 * now.mat[n+2][n]) % MOD;
          printf("%I64d
    " ,Ans);
       }
       return 0;
    }
    

  • 相关阅读:
    httpd sshd firewalld 服务后面的d的意思
    js parse_url 引发的
    python的shutil模块
    ubuntu18.04 LTS上安装并使用nvm管理node版本
    【ZIP】打包过滤指定目录和文件
    numpy中的reshape中参数为-1
    机器学习python常用模块
    Python3使运行暂停的方法
    thrift
    一个账号只能在一处登陆,不是单点登陆。
  • 原文地址:https://www.cnblogs.com/csnd/p/12062781.html
Copyright © 2011-2022 走看看