51nod 1242 斐波那契数列的第N项——数学、矩阵快速幂
普通算法肯定T了,所以怎么算呢?和矩阵有啥关系呢?
打数学符号太费时,就手写了:
所以求Fib(n)就是求矩阵 | 1 1 |n-1 第一行第一列的元素。
| 1 0 |
其实学过线代的同学应该一看就看出来了,然鹅我还没学,所以不得不写几个不必要的等式=。=
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 #define ll long long 5 #define INF 1000000009 6 7 ll n; 8 struct mat{ 9 ll c[2][2]; 10 }t; 11 12 mat matmult(mat a, mat b){ 13 mat c = {0}; 14 for(int i = 0; i < 2; i++) 15 for(int j = 0; j < 2; j++) 16 for(int k = 0; k < 2; k++) 17 c.c[i][j] = (c.c[i][j]+(a.c[i][k] * b.c[k][j])) % INF; 18 19 return c; 20 } 21 22 mat matpow(mat t,ll n){ 23 mat ans;//初始化为单位矩阵 24 ans.c[0][0]=ans.c[1][1]=1,ans.c[0][1]=ans.c[1][0]=0; 25 while(n){ 26 if(n&1) ans=matmult(ans, t); 27 t = matmult(t, t); 28 n >>= 1; 29 } 30 return ans; 31 } 32 int main(){ 33 while(cin>>n){ 34 t.c[0][0] = 1; 35 t.c[0][1] = 1; 36 t.c[1][0] = 1; 37 t.c[1][1] = 0; 38 mat ans = matpow(t,n-1); 39 //cout<<ans.c[0][0]<<' '<<ans.c[0][1]<<endl<<ans.c[1][0]<<' '<<ans.c[1][1]<<endl; 40 printf("%lld\n", ans.c[0][0]); 41 } 42 return 0; 43 }
Stay Hungry, Stay Foolish