矩阵幂可以用来解决斐波那契问题,图的路径条数问题。
在计算矩阵幂的过程中,如果用朴素的列与行枚举求和:
例如——
复杂度是O(N)。
所以引进了矩阵快速幂来计算。
首先来看快速幂——
快速幂就是把指数再化成 底数加指数 的形式,例如:
如何拆分呢?
快速幂模板:
ll quick(ll a,ll b ,ll c){
ll ans=1;
while(b){
if(b&1){
ans=(ans*a)%c;
}
b>>=1;
a=(a*a)%c;
}
return ans;
}
因为是指数再求指数所以时间复杂度为 O(log₂N)。
把它应用到矩阵运算中也是一样,把矩阵看成一个数。
放两个模板:
int n,m,T;
struct Node{
int contain[MAXX][MAXX];
Node(){
for(int i=0;i<MAXX;i++){
for(int j=0;j<MAXX;j++){
contain[i][j]=0;
}
}
}
};
矩阵乘法:
Node multi(int a[][MAXX],int b[][MAXX]){ //两矩阵乘
Node ans;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
for(int k=0;k<n;k++){
ans.contain[i][j]+=a[i][k]*b[k][j];
}
//ans.contain[i][j]%=10000;
}
}
return ans;
}
矩阵的快速幂:
Node Pow(Node ex,int k){//矩阵K次幂
Node res;
for(int i=0;i<n;i++){ //单位矩阵
res.contain[i][i]=1;
}
while(k){
if(k&1){
res=multi(res.contain,ex.contain);
}
ex=multi(ex.contain,ex.contain);
k>>=1;
}
return res;
}
用来解决斐波那契问题 即 把递推式转化成矩阵乘法的形式:
当然,没有公式的时候还是先要靠数学推出来的orz。
哦还有,多次幂得到的数很大超范围,一般都要取模。
一开始我很纠结取模的问题,为啥老模10000007。
它就是怕你范围太大,用个大素数把结果分散一点,有点哈希的意思。
不会影响结果的,总之,它要你怎么模就怎么模喽= =。