矩阵快速幂模板
两矩阵相乘,朴素算法的复杂度是O(N^3)
如果求一个矩阵的n次幂,就可以使用矩阵快速幂 可以降到复杂度为O(log)级别。
几乎任何递推的问题都可以用矩阵快速幂完成。
矩阵需要初始化,并不会默认为0!
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<set>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<string.h>
#include<string>
#include<math.h>
#define IOS; ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define VNAME(value) (#value)
#define debug(x) {cout<<VNAME(x)<<"="<<(x)<<endl;}
using namespace std;
const int N = 200000;
const int inf=0x3f3f3f3f;
typedef long long ll;
const int mod=9973;
int MatSize;
struct mat
{
ll m[10][10];
};
mat operator *(mat a,mat b)//重载矩阵乘法运算符,也可以用函数,重载了清楚一点。
{
ll x;
mat tmp;
for(int i=0;i<MatSize;i++)
for(int j=0;j<MatSize;j++)
{
x=0;
for(int k=0;k<MatSize;k++)
x+=(a.m[i][k]*b.m[k][j])%mod;
tmp.m[i][j]=x%mod;
}
return tmp;
}
mat mat_pow(mat a,int n)//矩阵快速幂
{
mat tmp;
for(int i=0;i<MatSize;i++)
for(int j=0;j<MatSize;j++)
tmp.m[i][j]=0;
for(int i=0;i<MatSize;i++)
tmp.m[i][i]=1;
tmp.m[0][1]=0;
tmp.m[1][0]=0;
//初始化为单位矩阵
while(n)//思想与快速幂相同,只不过换成了n*n的矩阵
{
if(n&1)tmp=tmp*a;
a=a*a;
n=n>>1;
}
return tmp;
}
void print(mat a)//输出矩阵
{
cout<<endl;
for(int i=0;i<MatSize;i++)
{
for(int j=0;j<MatSize;j++)
cout<<a.m[i][j]<<" ";
cout<<endl;
}
cout<<endl;
}
int main()//示例 求n*n 矩阵的k次幂 的主对角线和。
{
int t;cin>>t;
int k;
while(t--)
{
ll ans=0;
cin>>MatSize>>k;
mat a;
for(int i=0;i<MatSize;i++)
for(int j=0;j<MatSize;j++)
cin>>a.m[i][j];
a=mat_pow(a,k);
for(int i=0;i<MatSize;i++)
{
ans+=a.m[i][i];
ans%mod;
}
cout<<ans%mod<<endl;
}
}