矩阵快速幂是一种很有用的方法,具体作用就是让矩阵A^n的运算变成log(n)的时间复杂度;
因为矩阵里面A^2=A*A,A^4=A^2*A^2;所以说可以将一个n拆分成这样的运算,大大减少了时间复杂度,和快速幂差不多;
给一个题目用来理解
题目:http://120.78.128.11/Problem.jsp?pid=3089
1 #include<math.h> 2 #include<stdio.h> 3 #define ll long long 4 int M[40][2][2]={1, 1, 1, 0}, sav[2][2], sav1[2][2]; 5 int main( ) 6 { 7 int a, b, x, y; 8 int i, j, k, l, m, arr[100], top; 9 scanf("%d%d%d", &x, &y, &m); 10 for(i=1; i<33; i++) 11 for(j=0; j<2; j++) 12 for(k=0; k<2; k++) 13 for(l=0; l<2; l++) 14 M[i][j][k]=(M[i][j][k]+(ll)M[i-1][j][l]*M[i-1][l][k])%m;///预先处理好每一个矩阵,A的平方,A平方的平方………… 15 top=0; 16 y--; 17 sav[0][0]=sav[1][1]=1; 18 for(i=30; i>=0&&y; i--)///运算到结束为止 19 { 20 if(y>=1<<i) 21 y-=1<<i; 22 else 23 continue; 24 for(j=0; j<2; j++) 25 for(k=0; k<2; k++) 26 for(l=0; l<2; l++) 27 sav1[j][k]=(sav1[j][k]+(ll)sav[j][l]*M[i][l][k])%m; 28 for(j=0; j<2; j++) 29 for(k=0; k<2; k++) 30 sav[j][k]=sav1[j][k], sav1[j][k]=0; 31 } 32 a=((ll)(x*(1+sqrt(5))/2+x-1))%m; 33 b=((2*a-x+1)%m+m)%m; 34 printf("%d ", (b*sav[1][0]+a*sav[1][1])%m); 35 }