题目:给出一个矩阵A,计算A + A^2 + A^3 + ... + A^n。
解题思路:分治,快速模幂。设F(n)= A + A^2 + A^3 + ... + A^n则有F(n)= F(n/2)+ F(n/2)* A^(n/2)+ R(n为奇数存在R,为A^n) = F(n/2){E + A^(n/2)} + R。利用递归和分治求解即可。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
struct Matrix
{
long long int v[41][41];
Matrix()
{
memset(v,0,sizeof v);
}
}m,p;
Matrix sum(Matrix a,Matrix b,int n)
{
Matrix c;
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
c.v[i][j]=a.v[i][j]+b.v[i][j];
c.v[i][j]%=10;
}
}
return c;
}
Matrix mul(Matrix a,Matrix b,int n)
{
Matrix c;
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
for(int k=0; k<n; k++)
{
c.v[i][j]+=a.v[i][k]*b.v[k][j];
c.v[i][j]%=10;
}
}
}
return c;
}
Matrix pow(Matrix a,int k,int n)
{
Matrix sum=p;
while(k)
{
if(k&1) sum=mul(sum,a,n);
k>>=1;
a=mul(a,a,n);
}
return sum;
}
Matrix qpow(Matrix a,int k,int n)
{
if(k==1) return a;
Matrix b=qpow(a,k/2,n);
Matrix c=sum(p,pow(a,k/2,n),n);
if(k%2) return sum(mul(b,c,n),pow(a,k,n),n);
else return mul(b,c,n);
}
int main()
{
int n,k;
while(~scanf("%d %d",&n,&k)&&n)
{
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
scanf("%I64d",&m.v[i][j]);
m.v[i][j]%=10;
}
}
for(int i=0;i<n;i++)
p.v[i][i]=1;
Matrix e=m;
Matrix ans=qpow(e,k,n);
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
printf("%lld",ans.v[i][j]);
if(j==n-1) printf("\n");
else printf(" ");
}
}
printf("\n");
}
return 0;
}