POJ 3233Matrix Power Series

妈妈呀....这简直是目前死得最惨的一次。

贴题目:

http://poj.org/problem?id=3233

 

Matrix Power Series
Time Limit: 3000MS Memory Limit: 131072K
Total Submissions: 19128 Accepted: 8068

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 n nonnegative 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

Source

POJ Monthly--2007.06.03, Huang, Jinsong
首先我在克服重重困难后解决了矩阵的问题(工商管理第一学期还不学线性代数2333333)
 
原来的代码:
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <vector>
  6 #include <queue>
  7 #include <set>
  8 #include <map>
  9 #include <cmath>
 10 #include <cstdlib>
 11 
 12 #define rep(i,a,n) for(int i = a;i <= n;i++)
 13 #define per(i,n,a) for(int i = n;i>=a;i--)
 14 #define pb push_back
 15 #define VI vector<int>
 16 #define QI queue<int>
 17 #define logM(N) log10(N)/log10(M)
 18 #define eps 1e-8
 19 
 20 typedef long long ll;
 21 
 22 using namespace std;
 23 
 24 int n,m,k;
 25 
 26 struct node{
 27     ll mat[33][33];
 28 }h,sum;
 29 
 30 node operator * (const node &a,const node &b){
 31         node ret;
 32         memset(ret.mat,0,sizeof(ret.mat));
 33         rep(i,0,n-1){
 34             rep(j,0,n-1){
 35                 rep(k,0,n-1){
 36                     ret.mat[i][j] += (a.mat[i][k] * b.mat[k][j])%m;
 37                     //cout<<"a.mat["<<i<<"]["<<k<<"]="<<a.mat[i][k]<<" b.mat["<<k<<"]["<<j<<"]="<<b.mat[k][j]<<endl;
 38                     //cout<<"i = "<<i<<" j = "<<j<<" ret.mat["<<i<<"]["<<j<<"]="<<ret.mat[i][j]<<endl;
 39                 }
 40                 if(ret.mat[i][j] > m) ret.mat[i][j] %= m;
 41             }
 42         } 
 43         return ret;
 44 }
 45 
 46 node operator + (const node &a,const node &b){
 47     node ret;
 48     memset(ret.mat,0,sizeof(ret.mat));
 49     rep(i,0,n-1){
 50         rep(j,0,n-1){
 51             ret.mat[i][j] = a.mat[i][j] + b.mat[i][j];
 52             if(ret.mat[i][j] > m) ret.mat[i][j] %= m;
 53         }
 54     }
 55     return ret;
 56 }
 57 
 58 void pow_mod(int x){
 59     x--;
 60     node a,b;
 61     a = b = h;
 62     while(x){
 63         if(x&1) a = a * b;
 64         b = b * b;
 65         x >>= 1;
 66     }
 67     /*cout<<"========"<<endl;   
 68     rep(i,0,n-1){
 69         rep(j,0,n-1){
 70             printf("%d ",a.mat[i][j]);
 71         }puts("");
 72     }
 73     cout<<"========"<<endl;   
 74     */
 75     sum = sum + a;
 76 }
 77 
 78 int main()
 79 {
 80 #ifndef ONLINE_JUDGE
 81     freopen("in.txt","r",stdin);
 82     //freopen("out.txt","w",stdout);
 83 #endif
 84     while(~scanf("%d%d%d",&n,&k,&m)){
 85         memset(sum.mat,0,sizeof(sum.mat));
 86         rep(i,0,n-1){
 87             rep(j,0,n-1){
 88                 scanf("%I64d",&h.mat[i][j]);
 89             }
 90         }  
 91         rep(i,1,k){
 92             pow_mod(i);
 93         }
 94         rep(i,0,n-1){
 95             rep(j,0,n-1){
 96                 if(j != n-1){
 97                     printf("%I64d ",sum.mat[i][j]%m);
 98                 }
 99                 else{
100                     printf("%I64d\n",sum.mat[i][j]%m);
101                 }
102             }
103         }
104     } 
105     return 0;
106 }
View Code
其实在这边代码之前已经错了十多遍了。看了学姐的代码,也仔细审视了自己的代码。总的小小的零零碎碎的错误找出不少。
现在这个代码的情况就是TLE
估计里面的测试数据很大,还得优化一下,那么还可以优化的地方就是求sum这个地方。
原理直接盗用学姐给的图片:
POJ 3233Matrix Power Series_第1张图片
优化之后的代码:
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <vector>
  6 #include <queue>
  7 #include <set>
  8 #include <map>
  9 #include <cmath>
 10 #include <cstdlib>
 11 
 12 #define rep(i,a,n) for(int i = a;i <= n;i++)
 13 #define per(i,n,a) for(int i = n;i>=a;i--)
 14 #define pb push_back
 15 #define VI vector<int>
 16 #define QI queue<int>
 17 #define logM(N) log10(N)/log10(M)
 18 #define eps 1e-8
 19 
 20 typedef long long ll;
 21 
 22 using namespace std;
 23 
 24 int n,m,k;
 25 
 26 struct node{
 27     ll mat[33][33];
 28 }h,sum;
 29 
 30 node operator * (const node &a,const node &b){
 31         node ret;
 32         memset(ret.mat,0,sizeof(ret.mat));
 33         rep(i,0,n-1){
 34             rep(j,0,n-1){
 35                 rep(k,0,n-1){
 36                     ret.mat[i][j] += (a.mat[i][k] * b.mat[k][j])%m;
 37                 }
 38                 if(ret.mat[i][j] > m) ret.mat[i][j] %= m;
 39             }
 40         } 
 41         return ret;
 42 }
 43 
 44 node operator + (const node &a,const node &b){
 45     node ret;
 46     memset(ret.mat,0,sizeof(ret.mat));
 47     rep(i,0,n-1){
 48         rep(j,0,n-1){
 49             ret.mat[i][j] = a.mat[i][j] + b.mat[i][j];
 50             if(ret.mat[i][j] > m) ret.mat[i][j] %= m;
 51         }
 52     }
 53     return ret;
 54 }
 55 
 56 node pow_mod(int x){
 57     x--;
 58     node a,b;
 59     a = b = h;
 60     while(x){
 61         if(x&1) a = a * b;
 62         b = b * b;
 63         x >>= 1;
 64     }
 65     return a;
 66 }
 67 
 68 node work(int p){
 69     if(p == 1) return h;
 70     node ret = work(p>>1);
 71     ret = ret + ret * pow_mod(p>>1);
 72     if(p&1) ret = ret + pow_mod(p);
 73     return ret;
 74 }
 75 
 76 int main()
 77 {
 78 #ifndef ONLINE_JUDGE
 79     //freopen("in.txt","r",stdin);
 80     //freopen("out.txt","w",stdout);
 81 #endif
 82     while(~scanf("%d%d%d",&n,&k,&m)){
 83         memset(sum.mat,0,sizeof(sum.mat));
 84         rep(i,0,n-1){
 85             rep(j,0,n-1){
 86                 scanf("%I64d",&h.mat[i][j]);
 87             }
 88         }  
 89         sum = work(k);
 90         rep(i,0,n-1){
 91             rep(j,0,n-1){
 92                 if(j != n-1){
 93                     printf("%I64d ",sum.mat[i][j]%m);
 94                 }
 95                 else{
 96                     printf("%I64d\n",sum.mat[i][j]%m);
 97                 }
 98             }
 99         }
100     } 
101     return 0;
102 }
View Code

 

你可能感兴趣的:(POJ 3233Matrix Power Series)