POJ 3233 Matrix Power Series

Matrix Power Series
Time Limit: 3000MS Memory Limit: 131072K
Total Submissions: 26212 Accepted: 10784
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

构造矩阵,a0(A,E),a1(0,E);

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<map>
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
using namespace std;
const int MAXN=100+10;
const int inf=0x3f3f3f3f3f;
const int mod=1000000007;
int n,k,m;
struct matrix{
    ll x[33*3][33*3];
    matrix(){
        mem(x,0);
    }
};
matrix mul(matrix a,matrix b){
    matrix c;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            for(int k=1;k<=n;k++){
                c.x[i][j]=((a.x[i][k]*b.x[k][j])%m+c.x[i][j])%m;
            }
        }
    }
    return c;
}
matrix add(matrix a,matrix b){
    matrix c;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            c.x[i][j]=(a.x[i][j]+b.x[i][j])%m;
        }
    }
    return c;
}
matrix kum(matrix a,int i){
    matrix res;
    for(int i=1;i<=n;i++) res.x[i][i]=1;
    while(i){
        if(i&1){
            res=mul(res,a);}
        i>>=1;
        a=mul(a,a);
    }
    return res;
}
int main(){
    while(~scanf("%d%d%d",&n,&k,&m)){
        matrix a;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++)
                scanf("%d",&a.x[i][j]);
        }
        for(int i=1;i<=n;i++){
                a.x[i][n+i]=1;
                a.x[i+n][i+n]=1;
        }
        n*=2;
        matrix ans;
            ans=kum(a,k+1);
        n/=2;
        for(int i=1;i<=n;i++){
           if(i==1)ans.x[1][n+1]-=1;
            printf("%d",(ans.x[i][n+1]%m+m)%m);
            for(int j=n+2;j<=2*n;j++){
                if(i==j-n)ans.x[i][j]-=1;
                printf(" %d",(ans.x[i][j]%m+m)%m);
            }
            printf("\n");
        }
    }
}

另一种做法

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<map>
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
using namespace std;
int n,k,m;
struct matrix{
    int x[35][35];
};
matrix mul(matrix a,matrix b){
    matrix c;
    mem(c.x,0);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            for(int k=1;k<=n;k++){
                c.x[i][j]+=(a.x[i][k]*b.x[k][j]);
                c.x[i][j]%=m;
            }
        }
    }
    return c;
}
matrix add(matrix a,matrix b){
    matrix c;mem(c.x,0);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            c.x[i][j]=a.x[i][j]+b.x[i][j];
            c.x[i][j]%=m;
        }
    }
    return c;
}
matrix kum(matrix a,int i){
    matrix res;mem(res.x,0);
    for(int i=1;i<=n;i++) res.x[i][i]=1;
    while(i){
        if(i&1){
            res=mul(res,a);}
        i>>=1;
        a=mul(a,a);
    }
    return res;
}
matrix sum(matrix a,int k){
    if(k==1)return a;
    matrix t=sum(a,k/2);
    if(k&1){
        matrix x=kum(a,k/2+1);
        t=add(t,mul(x,t));
        t=add(t,x);
    }
    else{
        matrix x=kum(a,k/2);
        t=add(t,mul(t,x));
    }
    return t;
}
int main(){
    scanf("%d%d%d",&n,&k,&m);
        matrix a;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                scanf("%d",&a.x[i][j]);
                }
        }
        matrix ans=sum(a,k);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                printf("%d ",ans.x[i][j]);
            }
            printf("\n");
        }
}



posted @ 2018-04-26 21:09  _大美  阅读(112)  评论(0编辑  收藏  举报