- 原题如下:
Matrix Power Series
Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 28044 Accepted: 11440 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
- 题解:构造矩阵:
此时,令Sk=I+A+…+Ak-1,则有:
通过计算这个矩阵的k次幂,就可求出A的累乘和,时间复杂度为O(n3logk) - 代码:
1 #include <cstdio> 2 #include <cctype> 3 #define number s-'0' 4 #include <cstring> 5 #include <vector> 6 7 using namespace std; 8 9 typedef vector<int> vec; 10 typedef vector<vec> mat; 11 12 int n,k,m; 13 mat A; 14 15 void read(int &x) 16 { 17 char s; 18 x=0; 19 bool flag=0; 20 while (!isdigit(s=getchar())) 21 (s=='-')&&(flag=true); 22 for (x=number; isdigit(s=getchar());x=x*10+number); 23 (flag)&&(x=-x); 24 } 25 26 void write(int x) 27 { 28 if (x<0) 29 { 30 putchar('-'); 31 x=-x; 32 } 33 if (x>9) write(x/10); 34 putchar(x%10+'0'); 35 } 36 37 mat mul(mat &A, mat &B) 38 { 39 mat C(A.size(), vec(B[0].size())); 40 for (int i=0; i<A.size(); i++) 41 { 42 for (int j=0; j<B[0].size(); j++) 43 { 44 for (int k=0; k<B.size(); k++) 45 { 46 C[i][j]=(C[i][j]+A[i][k]*B[k][j])%m; 47 } 48 } 49 } 50 return C; 51 } 52 53 mat pow(mat A, int n) 54 { 55 mat B(A.size(), vec(A.size())); 56 for (int i=0; i<A.size(); i++) B[i][i]=1; 57 while (n>0) 58 { 59 if (n&1) B=mul(B, A); 60 A=mul(A, A); 61 n>>=1; 62 } 63 return B; 64 } 65 66 int main(int argc, char * argv[]) 67 { 68 read(n);read(k);read(m); 69 A=mat (n,vec(n)); 70 mat B(n*2, vec(n*2)); 71 for (int i=0; i<n; i++) 72 { 73 for (int j=0; j<n; j++) 74 { 75 read(A[i][j]); 76 B[i][j]=A[i][j]; 77 } 78 B[n+i][i]=B[n+i][n+i]=1; 79 } 80 B=pow(B,k+1); 81 for (int i=0; i<n; i++) 82 { 83 for (int j=0; j<n; j++) 84 { 85 int a=B[n+i][j]%m; 86 if (i==j) a=(a+m-1)%m; 87 printf("%d%c", a, j+1==n?' ':' '); 88 } 89 } 90 }