zoukankan      html  css  js  c++  java
  • poj 3233 Matrix Power Series ——矩阵快速幂+二分求解

    Matrix Power Series
    Time Limit: 3000MS   Memory Limit: 131072K
    Total Submissions:11389   Accepted: 4861

    Description

    Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak.

    Input

    The input contains exactly one test case. The first line of input contains three positive integers n (n ≤ 30), k (k ≤ 109) and m (m < 104). Then follow n lines each containing nnonnegative integers below 32,768, giving A’s elements in row-major order.

    Output

    Output the elements of S modulo m in the same way as A is given.

    Sample Input

    2 2 4
    0 1
    1 1

    Sample Output

    1 2
    2 3

    思路:矩阵的快速幂,又由于k比较大,并且要求的和是一个等比的数列,所以求解的时候可以用二分的方法。
    所谓二分,举例如下:
    求S = 2^1 + 2^2 + 2^3 + 2^4 的和。记为:maxsum(4)
    先求出 temp = maxsum(4/2); 再求出 b = 2^2;那么所要求的和就是 temp = add(temp, temp * b);
    然后在递归地求解maxsum(4/2)。
    上面是k是偶数的情况,同样地,如果k是奇数的时候,讨论一下就OK了。
    快速幂求(a^b)%m复杂度是log2(b).

    虽然是完书中的代码,然后自己敲的,但是竟然1A了……不科学……

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cctype>
     6 #include <stack>
     7 #include <queue>
     8 #include <cmath>
     9 #include <algorithm>
    10 using namespace std;
    11 #define LL long long
    12 #define lson l, m, rt<<1
    13 #define rson m+1, r, rt<<1|1
    14 typedef struct matrix{
    15   int a[33][33];
    16 }matrix;
    17 matrix A, B, per;
    18 int m, k, n;
    19 void init(){
    20   scanf("%d%d%d", &n, &k, &m);
    21   for (int i = 0; i < n; ++i){
    22     for (int j = 0; j < n; ++j){
    23       scanf("%d", &A.a[i][j]);
    24       A.a[i][j] %= m;
    25       per.a[i][j] = (i == j);
    26     }
    27   }
    28 }
    29 matrix add(matrix a, matrix b){
    30   matrix c;
    31   for (int i = 0; i < n; ++i){
    32     for (int j = 0; j < n; ++j){
    33       c.a[i][j] = 0; c.a[i][j] = (a.a[i][j] + b.a[i][j]) % m;
    34     }
    35   }
    36   return c;
    37 }
    38 matrix multi(matrix a, matrix b){
    39   matrix c;
    40   for (int i = 0; i < n; ++i){
    41     for (int j = 0;j < n; ++j){
    42       c.a[i][j] = 0;
    43       for (int k = 0; k < n; ++k){
    44         c.a[i][j] += (((a.a[i][k]%m) * (b.a[k][j]%m))%m);
    45       }
    46     }
    47   }
    48   return c;
    49 }
    50 matrix pow(int k){
    51   matrix ans = per, m = A;
    52   while (k){
    53     if (k&1){
    54       ans = (multi(ans, m)); k--;
    55     }
    56     k >>= 1; m = multi(m, m);
    57   }
    58   return ans;
    59 }
    60 matrix maxsum(int k){
    61   if (k == 1) return A;
    62   matrix temp = maxsum(k/2), b;
    63   if (k&1){
    64     b = pow(k/2+1); temp = add(temp, multi(temp, b));
    65     temp = add(temp, b);
    66   }
    67   else{
    68     b = pow(k/2); temp = add(temp, multi(temp, b));
    69   }
    70   return temp;
    71 }
    72 
    73 int main(void){
    74 #ifndef ONLINE_JUDGE
    75   freopen("3233.in", "r", stdin);
    76 #endif
    77   init();
    78   matrix ans = maxsum(k);
    79   int j, i;
    80   for (i = 0; i < n; ++i){
    81     for (j = 0; j < n-1; ++j){
    82       printf("%d ", ans.a[i][j]);
    83     }
    84     printf("%d\n", ans.a[i][j]);
    85   }
    86 
    87   return 0;
    88 }

    注意,求快速幂的时候,先把ans赋值成单位矩阵。

    有时间认真写一下快速幂的思想。

    突然赶脚自己的代码写得很挫……

  • 相关阅读:
    [SSRS] Use Enum values in filter expressions Dynamics 365 Finance and Operation
    Power shell deploy all SSRS report d365 FO
    display method in Dynamics 365 FO
    How To Debug Dynamics 365 Finance and Operation
    Computed columns and virtual fields in data entities Dynamics 365
    Azure DevOps for Power Platform Build Pipeline
    Create readonly entities that expose financial dimensions Dynamics 365
    Dataentity call stack dynamics 365
    Dynamics 365 FO extension
    Use singletenant servertoserver authentication PowerApps
  • 原文地址:https://www.cnblogs.com/liuxueyang/p/2995871.html
Copyright © 2011-2022 走看看