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 }

猜你喜欢

转载自www.cnblogs.com/noobimp/p/10344312.html