码迷,mamicode.com
首页 > 其他好文 > 详细

POJ3233 Matrix Power Series

时间:2016-09-24 17:29:47      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:

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
 
 
正解:矩乘快速幂+二分
解题报告;
  今天考试T1。
  考场上面推了一个上午的式子,好不容易发现一个,而且是一个log的,结果太复杂了,没调出来。最后没办法了,临时yy了一个两个log的方法,好歹也过了。
  考虑只有两种可能,题目相当于是要求一个前缀和,那么矩乘满足分配律,所以我们可以直接利用前面的结果乘起来就可以了。 
  还是数学题做少了,不会推式子,还是要多练。
 
  当然还有一个log的方法,就是直接倒着做,其余的完全相同。
 
  两个log:
 
 1 //It is made by jump~
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <ctime>
 9 #include <vector>
10 #include <queue>
11 #include <map>
12 #include <set>
13 using namespace std;
14 typedef long long LL;
15 #define RG register
16 int n,k,MOD;
17 int dui[45],tail;
18 
19 struct juz{
20     LL s[33][33];
21 }a,c[45],ini,mi[45];
22 
23 inline int getint()
24 {
25        RG int w=0,q=0;    char c=getchar();    while((c<0 || c>9) && c!=-) c=getchar();
26        if (c==-)  q=1, c=getchar();  while (c>=0 && c<=9) w=w*10+c-0, c=getchar();  return q ? -w : w;
27 }
28 
29 inline juz jia(juz p,juz q){
30     juz tmp;
31     for(RG int i=1;i<=n;i++)
32     for(RG int j=1;j<=n;j++)
33         tmp.s[i][j]=p.s[i][j]+q.s[i][j],tmp.s[i][j]%=MOD;
34     return tmp;
35 }
36 
37 inline juz cheng(juz p,juz q){
38     juz tmp;
39     for(RG int i=1;i<=n;i++) for(RG int j=1;j<=n;j++) tmp.s[i][j]=0;
40     for(RG int i=1;i<=n;i++)
41     for(RG int j=1;j<=n;j++)
42         for(RG int l=1;l<=n;l++)
43         tmp.s[i][j]+=p.s[i][l]*q.s[l][j],tmp.s[i][j]%=MOD;
44     return tmp;
45 }
46 
47 inline void work(){    
48     n=getint(); k=getint(); MOD=getint();    
49     for(RG int i=1;i<=n;i++) for(RG int j=1;j<=n;j++) ini.s[i][j]=getint();        
50     while(k>0) dui[++tail]=k,k>>=1; mi[tail]=ini; c[tail]=ini;
51     for(RG int i=tail-1;i>=1;i--) {
52     mi[i]=cheng(mi[i+1],mi[i+1]);//每次平方
53     c[i]=jia(c[i+1],cheng(c[i+1],mi[i+1]));//前面的乘以之前的部分再加上自己可降低复杂度
54     if(dui[i]&1) mi[i]=cheng(mi[i],ini),c[i]=jia(c[i],mi[i]);
55     }
56     for(RG int i=1;i<=n;i++) { for(RG int j=1;j<=n;j++) printf("%lld ",c[1].s[i][j]); printf("\n"); }
57 }
58 
59 int main()
60 {
61   work();
62   return 0;
63 }

 

一个log:

 1 //It is made by jump~
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <ctime>
 9 #include <vector>
10 #include <queue>
11 #include <map>
12 #include <set>
13 using namespace std;
14 typedef long long LL;
15 #define RG register
16 int n,k,MOD;
17 int dui[45],tail;
18 
19 struct juz{
20     LL s[33][33];
21 }a,c[45],ini,mi[45];
22 
23 inline int getint()
24 {
25        RG int w=0,q=0;    char c=getchar();    while((c<0 || c>9) && c!=-) c=getchar();
26        if (c==-)  q=1, c=getchar();  while (c>=0 && c<=9) w=w*10+c-0, c=getchar();  return q ? -w : w;
27 }
28 
29 inline juz jia(juz p,juz q){
30     juz tmp;
31     for(RG int i=1;i<=n;i++)
32     for(RG int j=1;j<=n;j++)
33         tmp.s[i][j]=p.s[i][j]+q.s[i][j],tmp.s[i][j]%=MOD;
34     return tmp;
35 }
36 
37 inline juz cheng(juz p,juz q){
38     juz tmp;
39     for(RG int i=1;i<=n;i++) for(RG int j=1;j<=n;j++) tmp.s[i][j]=0;
40     for(RG int i=1;i<=n;i++)
41     for(RG int j=1;j<=n;j++)
42         for(RG int l=1;l<=n;l++)
43         tmp.s[i][j]+=p.s[i][l]*q.s[l][j],tmp.s[i][j]%=MOD;
44     return tmp;
45 }
46 
47 inline void work(){    
48     n=getint(); k=getint(); MOD=getint();    
49     for(RG int i=1;i<=n;i++) for(RG int j=1;j<=n;j++) ini.s[i][j]=getint();        
50     while(k>0) dui[++tail]=k,k>>=1; mi[tail]=ini; c[tail]=ini;
51     for(RG int i=tail-1;i>=1;i--) {
52     mi[i]=cheng(mi[i+1],mi[i+1]);//每次平方
53     c[i]=jia(c[i+1],cheng(c[i+1],mi[i+1]));//前面的乘以之前的部分再加上自己可降低复杂度
54     if(dui[i]&1) mi[i]=cheng(mi[i],ini),c[i]=jia(c[i],mi[i]);
55     }
56     for(RG int i=1;i<=n;i++) { for(RG int j=1;j<=n;j++) printf("%lld ",c[1].s[i][j]); printf("\n"); }
57 }
58 
59 int main()
60 {
61   work();
62   return 0;
63 }

 

POJ3233 Matrix Power Series

标签:

原文地址:http://www.cnblogs.com/ljh2000-jump/p/5903458.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!