首页 > 代码库 > POJ 3233 Matrix Power Series 矩阵快速幂 + 二分

POJ 3233 Matrix Power Series 矩阵快速幂 + 二分

题意:求矩阵的次方和

解题思路:最容易想到方法就是两次二分因为 我们可以把一段  A^1 + A^2 + .......A^K   变成  A^1 + ..A^(K/2) +( A^1 + ..A^(K/2))*(A^(k/2)) 当k 为奇数的时候 或者 A^1 + ..A^(K/2) +( A^1 + ..A^(K/2))*(A^(k/2)) + A^K 当K 为偶数的时候。

解题代码:

  1 // File Name: temp.cpp  2 // Author: darkdream  3 // Created Time: 2014年09月17日 星期三 11时35分45秒  4   5 #include<vector>  6 #include<list>  7 #include<map>  8 #include<set>  9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #define LL long long 25 using namespace std; 26 int  n ,m , k ;  27 int  ta,tb; 28 struct Matrix 29 { 30    int   mat[30][30]; 31    void clear() 32    { 33       memset(mat,0,sizeof(mat)); 34    } 35    void output() 36    { 37      for(int i =0  ;i < n ;i ++) 38      { 39        for(int j = 0 ;j < n ;j ++) 40            printf("%d ",mat[i][j]); 41      printf("\n"); 42      } 43    } 44    void init() 45    { 46       clear(); 47       for(int i = 0 ;i < n;i ++) 48           for(int j = 0 ;j < n;j ++) 49           { 50             scanf("%d",&mat[i][j]); 51           } 52    } 53    Matrix operator *(const Matrix &b) const 54    { 55        Matrix ret; 56        ret.clear(); 57        for(int i = 0 ;i < n ;i ++) 58            for(int j = 0;j < n;j ++) 59            { 60                for(int s = 0 ;s < n ;s ++) 61                { 62                  ret.mat[i][j] =(ret.mat[i][j] + mat[i][s] * b.mat[s][j]) % m ; // 第I 行  第J  列         63                } 64            } 65        return ret; 66    } 67    Matrix operator *(const int  &b) const 68    { 69        Matrix ret; 70        ret.clear(); 71        for(int i = 0 ;i < n ;i ++) 72            for(int j = 0;j < n;j ++) 73            { 74                 ret.mat[i][j] = (mat[i][j] * b) % m ; // 第I 行  第J  列         75            } 76        return ret; 77    } 78    Matrix operator +(const Matrix &b) const 79    { 80        Matrix ret; 81        ret.clear(); 82        for(int i = 0 ;i < n ;i ++) 83            for(int j = 0;j < n;j ++) 84            { 85                 ret.mat[i][j] = (mat[i][j] + b.mat[i][j]) % m ; // 第I 行  第J  列         86            } 87        return ret; 88    } 89 }; 90 Matrix Pow( Matrix a ,LL t ) 91 { 92   Matrix ret; 93   ret.clear(); 94   for(int i = 0 ;i < n ;i ++) 95        ret.mat[i][i] = 1; 96   Matrix tmp = a;  97   while(t) 98   { 99       if(t&1) ret = ret * tmp;100       tmp = tmp * tmp;101       t >>=1;102   }103   return ret;104 }105 Matrix add(Matrix a, int k )106 {107     Matrix ans;108     ans.clear();109     if(k == 1)110     {111       return a;112     }113     if(k&1)114     {115           Matrix temp = add(a,k/2);116           ans = temp + temp * Pow(a,k/2) + Pow(a,k);117     }else{118           Matrix temp = add(a,k/2);119           ans = temp + temp * Pow(a,k/2);120     }121     return ans ; 122 }123 int main(){124     LL l ;125     while(scanf("%d %d %d",&n,&k,&m) != EOF)126     {127         Matrix  a;128         a.clear();129         a.init();130         a = add(a,k);131         //a.output();132         a.output();133     }134     return 0;135 }
View Code

写完以后过了竟然跑了 1300+ms  最快 0ms  不能忍上网查题解 发现了这种方法 :http://www.cnblogs.com/rainydays/archive/2011/02/21/1960189.html

他的主要思想是多加 n维度 构成一个能累加的矩阵 ,具体看博主题解。

这种思想很巧妙。

 

POJ 3233 Matrix Power Series 矩阵快速幂 + 二分