POJ 3233 Matrix Power Series

来源:互联网 发布:软件ui设计 编辑:程序博客网 时间:2024/04/23 23:08

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 ;}


0 0