题目大意:
给你一个矩阵A,求A^1+A^2+A^3+...+A^n
解题思路:
利用和快速幂一样的思想,我们可以对原式变形。
当n为偶数的时候:
当n为奇数的时候:
所以,我们就可以用递归每次先求出n/2的前n项和,然后利用矩阵快速幂和上面的式子得到前n项和。时间复杂度为O(logn*logn)。
AC代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <vector>
#include <queue>
#include <stack>
#include <deque>
#include <string>
#include <map>
#include <set>
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long
#define fi first
#define se second
#define mem(a,b) memset((a),(b),sizeof(a))
const int MOD=10;
const int MAXN=40;
int N,K;
struct Matrix
{
int a[MAXN][MAXN];
Matrix()
{
memset(a,0,sizeof(a));
}
void init()
{
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
a[i][j]=(i==j);
}
Matrix operator + (const Matrix &B)const
{
Matrix C;
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
C.a[i][j]=(a[i][j]+B.a[i][j]+MOD)%MOD;
return C;
}
Matrix operator * (const Matrix &B)const
{
Matrix C;
for(int i=0;i<N;i++)
for(int k=0;k<N;k++)
for(int j=0;j<N;j++)
C.a[i][j]=(C.a[i][j]+1LL*a[i][k]*B.a[k][j]+MOD)%MOD;
return C;
}
Matrix operator ^ (const int &t)const
{
Matrix A=(*this),res;
res.init();
int p=t;
while(p)
{
if(p&1)res=res*A;
A=A*A;
p>>=1;
}
return res;
}
};
Matrix solve(Matrix a,int n)
{
if(n==1)
return a;
Matrix tmp=solve(a,n/2);//得到前n/2项的和
Matrix res=tmp+tmp*(a^(n/2));//计算出前n项和
if(n&1)
res=res+(a^n);//如果是奇数还要额外加上a^n
return res;
}
int main()
{
while(~scanf("%d%d",&N,&K)&&N)
{
Matrix A;
for(int i=0;i<N;++i)
for(int j=0;j<N;++j)
{
scanf("%d",&A.a[i][j]);
A.a[i][j]%=10;
}
A=solve(A,K);
for(int i=0;i<N;++i)
for(int j=0;j<N;++j)
printf("%d%c",A.a[i][j],j==N-1?'\n':' ');
putchar('\n');
}
return 0;
}