POJ 3070 Fibonacci(快速幂矩阵)
题目链接
不是很了解,线代的行列式和矩阵乘法,忘的差不多了。。。
这个矩阵的n-1次方的左上角那个数就是菲薄那切数列的第n项。快速幂矩阵,和快速幂模差不多,把数相乘换成矩阵相乘了。
渣代码请无视,改天整理一个模版版本。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 using namespace std; 6 #define MOD 10000 7 #define LL __int64 8 int mat[3][3],p[3][3]; 9 void mulp() 10 { 11 int i,j,k; 12 int temp[3][3]; 13 memset(temp,0,sizeof(temp)); 14 for(i = 1;i <= 2;i ++) 15 { 16 for(j = 1;j <= 2;j ++) 17 { 18 for(k = 1;k <= 2;k ++) 19 { 20 temp[i][j] += (mat[i][k]*p[k][j])%MOD; 21 } 22 } 23 } 24 for(i = 1;i <= 2;i ++) 25 { 26 for(j = 1;j <= 2;j ++) 27 mat[i][j] = temp[i][j]%MOD; 28 } 29 } 30 void mulm() 31 { 32 int i,j,k; 33 int temp[3][3]; 34 memset(temp,0,sizeof(temp)); 35 for(i = 1;i <= 2;i ++) 36 { 37 for(j = 1;j <= 2;j ++) 38 { 39 for(k = 1;k <= 2;k ++) 40 { 41 temp[i][j] += (p[i][k]*p[k][j])%MOD; 42 } 43 } 44 } 45 for(i = 1;i <= 2;i ++) 46 { 47 for(j = 1;j <= 2;j ++) 48 p[i][j] = temp[i][j]%MOD; 49 } 50 } 51 void qmod(LL n) 52 { 53 while(n) 54 { 55 if(n&1) 56 mulp(); 57 mulm(); 58 n >>= 1; 59 } 60 } 61 int main() 62 { 63 LL n; 64 while(scanf("%I64d",&n)!=EOF) 65 { 66 if(n < 0) 67 break; 68 p[1][1] = p[1][2] = p[2][1] = 1; 69 p[2][2] = 0; 70 mat[1][1] = mat[2][2] = 1; 71 mat[1][2] = mat[2][1] = 0; 72 if(n == 0) 73 { 74 printf("0\n"); 75 continue; 76 } 77 qmod(n-1); 78 printf("%d\n",mat[1][1]%MOD); 79 } 80 return 0; 81 }