题目链接:
http://poj.org/problem?id=3233
题目大意:
给定一个N*N的矩阵A和一个整数K,要求计算S = A + A^2 + A^3 + … + A^k。
思路:
分别用矩阵快速幂求出每一项的A^i,然后将每一项矩阵相加,考虑到k值很大,所有采用
二分求解。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 110;
struct Matrax
{
int m[MAXN][MAXN];
}a,per;
int N,M;
void Init()
{
for(int i = 0; i < N; ++i)
for(int j = 0; j < N; ++j)
{
scanf("%d",&a.m[i][j]);
a.m[i][j] %= M;
per.m[i][j] = (i == j);
}
}
Matrax Add(Matrax a,Matrax b)
{
Matrax c;
for(int i = 0; i < N; ++i)
{
for(int j = 0; j < N; ++j)
{
c.m[i][j] = (a.m[i][j] + b.m[i][j]) % M;
}
}
return c;
}
Matrax Multi(Matrax a,Matrax b)
{
Matrax c;
for(int i = 0; i < N; ++i)
{
for(int j = 0; j < N; ++j)
{
c.m[i][j] = 0;
for(int k = 0; k < N; ++k)
{
c.m[i][j] += a.m[i][k] * b.m[k][j];
}
c.m[i][j] %= M;
}
}
return c;
}
Matrax Power(int k)
{
Matrax p,ans = per;
p = a;
while(k)
{
if(k&1)
{
ans = Multi(ans,p);
k--;
}
else
{
k >>= 1;
p = Multi(p,p);
}
}
return ans;
}
Matrax MatraxSum(int k)
{
if(k == 1)
return a;
Matrax temp,b;
temp = MatraxSum(k/2);
if(k&1)
{
b = Power(k/2+1);
temp = Add(temp,Multi(temp,b));
temp = Add(temp,b);
}
else
{
b = Power(k/2);
temp = Add(temp,Multi(temp,b));
}
return temp;
}
int main()
{
int k;
while(~scanf("%d%d%d",&N,&k,&M))
{
Init();
Matrax ans = MatraxSum(k);
for(int i = 0; i < N; ++i)
{
for(int j = 0; j < N-1; ++j)
{
printf("%d ",ans.m[i][j]);
}
printf("%d\n",ans.m[i][N-1]);
}
}
return 0;
}