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赋值成单位矩阵。

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

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

  • 相关阅读:
    spring中@Lookup的作用
    spring中的观察者模式
    spring事务源码解析
    spring中@Configuration注解的作用
    HTML5和CSS3
    TCP/IP协议
    Android项目的settings.gradle和build.gradle
    AndroidManifest.xml 最全详解
    Android实现网络监听
    Android数据存取
  • 原文地址:https://www.cnblogs.com/liuxueyang/p/2995871.html
Copyright © 2011-2022 走看看