Poj 3233 Matrix Power Series(矩阵乘法)

Matrix Power Series
Time Limit: 3000MS Memory Limit: 131072K
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
Source
POJ Monthly–2007.06.03, Huang, Jinsong
给定矩阵A,求A + A^2 + A^3 + … + A^k的结果

/*
矩阵乘法经典题.
一开始并没有想出来orz.
发现正解好神奇.
这种题就应该先推出递推式子再构造矩阵.
本来还想矩阵套矩阵来着
弱啊.
学习了一下单位矩阵的用法.
题解:http://www.cnblogs.com/justPassBy/p/4448630.html 
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#define MAXN 61
#define LL long long
using namespace std;
LL n,m,k,ans[MAXN][MAXN],b[MAXN][MAXN],c[MAXN][MAXN];
LL mul(LL x,LL y)
{
    LL tot=0;
    while(y)
    {
        if(y&1) tot=(tot+x)%m;
        x=(x+x)%m;
        y>>=1;
    }
    return tot;
}
void mi()
{
    while(k)
    {
        if(k&1)
        {
            for(int i=1;i<=n*2;i++)
              for(int j=1;j<=n*2;j++)
                for(int k=1;k<=n*2;k++)
                  c[i][j]=(c[i][j]+ans[i][k]*b[k][j]%m)%m;
            for(int i=1;i<=n*2;i++)
              for(int j=1;j<=n*2;j++)
                ans[i][j]=c[i][j],c[i][j]=0;
        }
        for(int i=1;i<=n*2;i++)
          for(int j=1;j<=n*2;j++)
            for(int k=1;k<=n*2;k++)
              c[i][j]=(c[i][j]+b[i][k]*b[k][j]%m)%m;
        for(int i=1;i<=n*2;i++)
          for(int j=1;j<=n*2;j++)
            b[i][j]=c[i][j],c[i][j]=0;
        k>>=1;
    }
}
void slove()
{
    k--;
    mi();
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
          cout<<ans[i][j]<<" ";
        printf("\n");
    }
}
void Clear()
{
    memset(b,0,sizeof b);
    memset(ans,0,sizeof ans);
}
int main()
{
    while(~scanf("%lld%lld%lld",&n,&k,&m))
    {
        Clear();
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                cin>>b[i][j];b[i][j]%=m;
                ans[i][j]=ans[i][n+j]=b[i][j];
            }
            b[n+i][i]=b[n+i][n+i]=1;
        }
        slove();
    }
    return 0;
}
posted @ 2017-03-23 08:45  nancheng58  阅读(126)  评论(0编辑  收藏  举报