• UVA-11149 Power of Matrix(矩阵二分幂)


    题目大意:给一个n阶方阵,求A1+A2+A3+......Ak

    题目分析:令F(k)=A1+A2+A3+......Ak。当k为偶数时,F(k)=F(k/2)*(E+Ak/2),k为奇数时,F(k)=F(k/2)*(E+Ak/2)+Ak。证明这两条公式也很简单,把这两条公式展开就行了。根据公式,递归即可。

    代码如下:

     1 # include<iostream>
     2 # include<cstdio>
     3 # include<cstring>
     4 # include<algorithm>
     5 using namespace std;
     6 struct matrix
     7 {
     8     int r,c,m[45][45];
     9     matrix(int _r,int _c):r(_r),c(_c){}
    10 };
    11 matrix multiply(matrix a,matrix b)
    12 {
    13     matrix c(a.r,b.c);
    14     for(int i=1;i<=c.r;++i){
    15         for(int j=1;j<=c.c;++j){
    16             c.m[i][j]=0;
    17             for(int k=1;k<=a.c;++k){
    18                 c.m[i][j]+=(a.m[i][k]%10)*(b.m[k][j]%10);
    19                 c.m[i][j]%=10;
    20             }
    21         }
    22     }
    23     return c;
    24 }
    25 matrix mypow(matrix a,int n)
    26 {
    27     if(n==0){
    28         for(int i=1;i<=a.r;++i)
    29             for(int j=1;j<=a.c;++j)
    30                 a.m[i][j]=(i==j)?1:0;
    31         return a;
    32     }
    33     if(n==1)
    34         return a;
    35     matrix res=mypow(a,n/2);
    36     res=multiply(res,res);
    37     if(n&1)
    38         res=multiply(res,a);
    39     return res;
    40 }
    41 matrix add(matrix a,matrix b)
    42 {
    43     for(int i=1;i<=a.r;++i)
    44         for(int j=1;j<=a.c;++j){
    45             a.m[i][j]+=b.m[i][j];
    46             a.m[i][j]%=10;///忘记取模,WA很多次。
    47         }
    48     return a;
    49 }
    50 matrix work(matrix mat,int k)
    51 {
    52     if(k==0){
    53         for(int i=1;i<=mat.r;++i)
    54             for(int j=1;j<=mat.c;++j)
    55                 mat.m[i][j]=(i==j)?1:0;
    56         return mat;
    57     }
    58     if(k==1)
    59         return mat;
    60     matrix res=work(mat,k/2);
    61     matrix one(mat.r,mat.c);
    62     for(int i=1;i<=one.r;++i)
    63         for(int j=1;j<=one.c;++j)
    64             one.m[i][j]=(i==j)?1:0;
    65     one=add(one,mypow(mat,k/2));
    66     res=multiply(res,one);
    67     if(k&1)
    68         res=add(res,mypow(mat,k));
    69     return res;
    70 }
    71 int main()
    72 {
    73     int n,k;
    74     while(scanf("%d%d",&n,&k)&&n)
    75     {
    76         matrix mat(n,n);
    77         for(int i=1;i<=n;++i){
    78             for(int j=1;j<=n;++j){
    79                 scanf("%d",&mat.m[i][j]);
    80                 mat.m[i][j]%=10;
    81             }
    82         }
    83         matrix ans=work(mat,k);
    84         for(int i=1;i<=ans.r;++i){
    85             printf("%d",ans.m[i][1]);
    86             for(int j=2;j<=ans.c;++j)
    87                 printf(" %d",ans.m[i][j]);
    88             printf("
    ");///没注意格式,WA很多次!!!
    89         }
    90         printf("
    ");
    91     }
    92     return 0;
    93 }
  • 相关阅读:
    CCF-Python的内置函数们
    CCF2019-03-Python题解
    Find a Number (记忆化+BFS)
    LeetCode15:三数之和(双指针)
    LeetCode:不用加号的加法(位运算)
    剑指Offer43:1~n整数中1出现的次数(数位DP)
    LeetCode190:颠倒二进制(位运算分治! 时间复杂度O(1))
    LeetCode5716:好因子的最大数目(数学、快速幂)
    python学习笔记:python的字符串拼接效率分析
    LeetCode1806:还原排列的最少操作步数(置换群 or 模拟)
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4740143.html
Copyright © 2020-2023  润新知