Matrix Power Series
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 Source
POJ Monthly--2007.06.03, Huang, Jinsong
|
题意是给你一个n * n的矩阵A和k , m 。S = A + A ^ 2 + A ^ 3 + …… A ^ k 对m取模后的结果。
显然不能直接去矩阵快速幂,我们构建一个矩阵{{A , 0 } , {I , I}};
可以算出{ {A^k} , {S} } = { {A , 0} , {I , I} } ^ k * { {I} , {0} };
没有画图工具只能文字描述了。。。
#include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #include <cstring> #include <map> #include <string> #include <stack> #include <cctype> #include <vector> #include <queue> #include <set> #include <utility> #include <cassert> using namespace std; ///#define Online_Judge #define outstars cout << "***********************" << endl; #define clr(a,b) memset(a,b,sizeof(a)) #define lson l , mid , rt << 1 #define rson mid + 1 , r , rt << 1 | 1 #define mk make_pair #define FOR(i , x , n) for(int i = (x) ; i < (n) ; i++) #define FORR(i , x , n) for(int i = (x) ; i <= (n) ; i++) #define REP(i , x , n) for(int i = (x) ; i > (n) ; i--) #define REPP(i ,x , n) for(int i = (x) ; i >= (n) ; i--) const int MAXN = 50 + 5; const int MAXS = 10000 + 50; const int sigma_size = 26; const long long LLMAX = 0x7fffffffffffffffLL; const long long LLMIN = 0x8000000000000000LL; const int INF = 0x7fffffff; const int IMIN = 0x80000000; const int inf = 1 << 30; #define eps 1e-8 const long long MOD = 1000000000 + 7; const int mod = 10007; typedef long long LL; const double PI = acos(-1.0); typedef double D; typedef pair<int , int> pii; typedef vector<int> vec; typedef vector<vec> mat; #define Bug(s) cout << "s = " << s << endl; ///#pragma comment(linker, "/STACK:102400000,102400000") int n , m; int k; mat A; mat mul(mat & A , mat & B) { mat C(A.size() , vec(B[0].size())); for(int i = 0 ; i < A.size() ; i++) { for(int k = 0 ; k < B.size() ; k++) { for(int j = 0 ; j < B[0].size() ; j++) { C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % m; } } } return C; } mat pow(mat A , LL n) { mat B(A.size() , vec(A.size())); for(int i = 0 ; i < A.size() ; i++)B[i][i] = 1; while(n > 0) { if(n & 1)B = mul(B , A); A = mul(A , A); n >>= 1; } return B; } void solve() { mat B(n * 2 , vec(n * 2)); FOR(i , 0 , n) { FOR(j , 0 , n) { B[i][j] = A[i][j]; } B[n + i][i] = B[n + i][n + i] = 1; } B = pow(B , k + 1); FOR(i , 0 , n) { FOR(j ,0 , n) { int a = B[n + i][j] % m; if(i == j)a = (a + m - 1) % m; printf("%d%c" , a , j == n - 1 ? '\n' : ' '); } } } int main() { while(~scanf("%d%d%d" , &n , &k , &m)) { int xx; A.clear(); // FOR(i , 0 , n)A[i].clear(); FOR(i , 0 , n) { vec x; FOR(j , 0, n) { scanf("%d" , &xx); x.push_back(xx); } A.push_back(x); } solve(); } return 0; }