一个矩阵求它的n次幂,可以把矩阵看成是变量,通过快速幂(快速幂见快速幂总结)的方法来求
前提小知识:俩个矩阵能够相乘那么前一个矩阵的行数和后一个矩阵的列数是相同的,所以如果是幂的话这个矩阵就是n行n列的
struct matrix{
int m[n][n];//n行 n列
matrix(){memset(m,0,sizeof(m));}
};
matrix matrix_mul(matrix a,matrix b,int Mod){
matrix c;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
for(int k=0;k<n;k++){
c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j])%Mod;
}
}
}
return c;
}
matrix matrix_pow(matrix a,int b){//b次方
matrix c;
for(int i=0;i<n;i++){
c.m[i][i]=1;//c为单位矩阵
}
while(b){
if(b&1){
c=matrix_mul(c,a);
}
a=matrix_mul(a,a);
b>>=1;
}
return c;
}
上面代码复杂度为O(n3log2b);
一个矩阵中,如果第一项和第二、三、四项…有关,要求出第n项时,我们可以尝试把地推关系转换成矩阵
举个例子,最常见的前后项有关的斐波那契数列:
a[0]=0,a[1]=1;
a[2]=a[1]+a[0]=1;
a[3]=a[2]+a[1]=2;
...
a[n]=a[n-1]+a[n-2];
a[n+1]=a[n]+a[n-1];
//要求n+1项必须知道第n项和第n-1项
[ a[2] a[1] a[0] ]*(matrix B)=[ 1 1 0 ]*B=[ a[3] a[2] a[1] ]
[ a[3] a[2] a[1] ]=[ a[2]+a[1] a[2] a[1] ]
=[ 1*a[2]+1*a[1]+0*a[0] 1*a[2]+0*a[1]+0*a[0] 0*a[2]+1*a[1]+0*a[0] ]
1*a[2]+1*a[1]+0*a[0]: 1 1 0
1*a[2]+0*a[1]+0*a[0]: 1 0 0
0*a[2]+1*a[1]+0*a[0]: 0 1 0
将每行竖的写
得到矩阵B为
1 1 0
1 0 1
0 0 0
所以若矩阵A【 a[2] a[1] a[0]】则矩阵C【 a[n] a[n-1] a[n-2]】=A*Bn-2
再举一个例子已知f[i]=f[i-1]+2xf[i-2]+i4,f[1]=a,f[2]=b
则 f[i+1]=f[i]+2xf[i-1]+(i+1)4
= f[i]+2xf[i-1]+i4+4xi3+6xi2+4xi+1
f[2] f[1] 2^4 2^3 2^2 2 1
[ b a 16 8 4 2 1 ]
f[3]= f[2]+2xf[1]+24+4x23+6x22+4x2+1
f[2]=f[2]
34=24+4x23+6x22+4x2+1
33=1x23+3x22+3x2+1
32=1x2+1
1=1
按照f[2] f[1] 24 23 22 2 1的顺序依次给出系数,并且竖着排列得到:
1 1 0 0 0 0 0
2 0 0 0 0 0 0
1 0 1 0 0 0 0
4 0 4 1 0 0 0
6 0 6 3 1 0 0
4 0 4 3 2 1 0
1 0 1 1 1 1 1
上面这个就是矩阵B了
也是C=A*Bn-2
矩阵C=[ f[n] f[n-1] n4 n3 n2 n1 1]
一个小练习:Happy Necklace