http://poj.org/problem?id=3233
分析表达式,等比矩阵求和
sum(k) = A + A^2 + A^3+...A^k . k 太大
容易联想到求矩阵高次幂。
sum(k-1) + A^k = sum(k) . 有这个特性,构造出
矩阵:
|A 1| ans[0][0] 每次相乘得到A^x , ans[0][1] 每次把ans[0][0] 项加之 ,得到(1+A+A^2+...+A^(k))
|0 1|
原题简化为求该矩阵的k+1次幂。矩阵快速幂即可。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
using namespace std;
const int maxn = 80 ;
struct matrix{
int r , c ;
long long mp[maxn][maxn] ;
};
//void debug( const matrix &ans ){
// cout << "....................." <<endl ;
// for(int i = 0 ;i < ans.r ; ++i){
// for(int j = 0; j < ans.c-1 ; ++j){
// cout<< ans.mp[i][j] << " " ;
// }
// cout << ans.mp[i][ans.c-1] << endl ;
// }
// cout << "....................." <<endl ;
//}
matrix mul(matrix a , matrix b , const int & mod){
matrix tmp ;
memset(tmp.mp,0,sizeof(tmp.mp)) ;
for(int i = 0 ; i < a.r ; ++i){
for(int j = 0 ; j < b.c ; ++j){
for(int k = 0 ; k < a.c ; ++k){
tmp.mp[i][j] = (tmp.mp[i][j] + (a.mp[i][k]*b.mp[k][j])%mod)%mod ;
}
}
}
tmp.r = a.r ;
tmp.c = b.c ;
return tmp ;
}
matrix quick( matrix &tmp , matrix & ans , const int & n , const int & mod , long long & k){
k++;
while(k){
if(k&1){
ans = mul(ans,tmp,mod) ;
}
tmp = mul(tmp,tmp,mod) ;
k>>=1 ;
}
return ans ;
}
void prin(matrix &ans , const int &n){
for(int i = 0; i < n; ++i){
for(int j = 0 ;j < n-1; ++j){
cout << ans.mp[i][j+n] <<" " ;
}
cout << ans.mp[i][(n<<1)-1] << endl;
}
}
void sub(matrix & ans , const int &n , const int & mod){
for(int i = 0 ;i < n; ++i){
ans.mp[i][i+n] =(ans.mp[i][i+n]-1+mod)%mod ;
}
prin(ans,n) ;
}
void input(const int & n , long long & k , const int & m){
matrix ans ,A ;
memset(ans.mp , 0 , sizeof(ans.mp)) ;
memset(A.mp,0,sizeof(A.mp)) ;
A.r = A.c = n<<1 ;
ans.r = ans.c = n<<1 ;
for(int i = 0 ;i < n ;++i){
for(int j = 0 ;j < n; ++j){
cin >> A.mp[i][j] ;
A.mp[i][j]%=m ;
}
A.mp[i][i+n] = A.mp[i+n][i+n] = 1 ;
ans.mp[i][i] = ans.mp[i+n][i+n] = 1 ;
}
//debug(ans) ;
//system("pause") ;
quick(A,ans,n,m,k) ;
sub(ans,n,m) ;
}
int main(){
int n , m ;
long long k ;
while(cin >> n >> k >> m){
input(n,k,m) ;
}
return 0 ;
}