• UVA11149 矩阵快速幂


    先我们来想一下计算A+A^2+A^3...+A^k。

    如果A=2,k=6。那你怎么算                        

    2+22+23+24+25+26 = ?= (2+22+23)*(1+23)

    如果A=2,k=7。那你怎么算                        

    2+22+23+24+25+26+2= ?= (2+22+23)*(1+23)+27

    so....同理:

    当k是偶数,A+A^2+A^3...+A^k=(E+A^(k/2))*(A+A^2...+A^(k/2))。

    当k是奇数,A+A^2+A^3...+A^k=(E+A^(k/2))*(A+A^2...+A^(k/2))+A^k。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cstdlib>
     5 using namespace std;
     6 #define MAXN 50
     7 int n,K;
     8 struct node
     9 {
    10     int mat[MAXN][MAXN];
    11 };
    12 node calcu(node x, node y)
    13 {
    14     node ret;
    15     memset(ret.mat,0,sizeof(ret.mat));
    16     for (int i = 1; i <= n ; i++)
    17         for (int j = 1; j <= n ; j++)
    18     {
    19         for (int k = 1; k <= n ; k++)
    20             ret.mat[i][j] = (ret.mat[i][j] + x.mat[i][k] * y.mat[k][j]) % 10;
    21     }
    22     return ret;
    23 }
    24 node add(node x,node y)
    25 {
    26     node ret;
    27     memset(ret.mat,0,sizeof(ret.mat));
    28     for (int i = 1; i <= n ; i++)
    29         for (int j = 1; j <= n ; j++)
    30    {
    31            ret.mat[i][j] = x.mat[i][j] + y.mat[i][j];
    32            ret.mat[i][j] %= 10;
    33    }
    34    return ret;
    35 }
    36 node pow_mat(node x,int cnt)
    37 {
    38     node ret;
    39     memset(ret.mat,0,sizeof(ret.mat));
    40     for (int i = 1; i < MAXN ; i++) ret.mat[i][i] = 1;
    41     while (cnt)
    42     {
    43         if (cnt & 1) ret = calcu(ret,x);
    44         x = calcu(x,x);
    45         cnt >>= 1;
    46     }
    47     return ret;
    48 }
    49 node dfs(node cur, int k)
    50 {
    51     if (k == 1) return cur;
    52     node res = dfs(cur,k / 2);
    53     node ans;
    54     ans = add(res,calcu(res,pow_mat(cur,k / 2)));
    55     if (k & 1) ans = add(ans,pow_mat(cur,k));
    56     return ans;
    57 }
    58 int main()
    59 {
    60     while (scanf("%d%d",&n,&K) != EOF)
    61     {
    62         if (n == 0) break;
    63         node ans;
    64         for (int i = 1; i <= n ; i++)
    65                 for (int j = 1; j <= n ; j++) {scanf("%d",&ans.mat[i][j]); ans.mat[i][j] %= 10;}
    66         node ret = dfs(ans,K);
    67         for (int i = 1; i <= n ; i++)
    68         {
    69                 printf("%d",ret.mat[i][1]);
    70                 for (int j = 2; j <= n ; j++)
    71                         printf(" %d",ret.mat[i][j]);
    72                 putchar('
    ');
    73         }
    74         putchar('
    ');
    75     }
    76     return 0;
    77 }
  • 相关阅读:
    综合实例-文本框类部件
    输入掩码
    WebP,Jpeg,Png格式图片的编解码区别
    美团点评提前批面经
    Android中AIDL的使用详解,如何发起回调?
    JNI在Android中的实践NDK:Hello World
    Timer实现原理
    百度秋招凉经:客户端测开
    阿里秋招面经:Android客户端开发工程师
    Picasso和Glide区别
  • 原文地址:https://www.cnblogs.com/ACMERY/p/4372019.html
Copyright © 2020-2023  润新知