51Nod - 1242 斐波那契数列的第N项

斐波那契数列的定义如下:

 
F(0) = 0
F(1) = 1
F(n) = F(n - 1) + F(n - 2) (n >= 2)
 
(1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, ...)
给出n,求F(n),由于结果很大,输出F(n) % 1000000009的结果即可。
 

Input输入1个数n(1 <= n <= 10^18)。Output输出F(n) % 1000000009的结果。Sample Input

11

Sample Output

89

用o(logn)方法解。

 1 #include <cstdio>  
 2 #include <iostream>  
 3 #include <vector>   
 4 using namespace std; 
 5 typedef long long ll; 
 6 typedef vector<long long> vec;  
 7 typedef vector<vec> mat;    
 8 const ll N = 1000000009;  
 9 mat mul(mat a,mat b)  
10 {  
11     mat c(a.size(),vec(b[0].size()));  
12     for(ll i=0;i<a.size();i++)  
13     {  
14         for(ll k=0;k<b.size();k++)  
15         {  
16             for(ll j=0;j<b[0].size();j++)  
17                 c[i][j] = ( c[i][j] + a[i][k] * b[k][j] ) % N;  
18         }  
19     }  
20     return c;  
21 }  
22   
23 mat solve_pow(mat a,ll n)  
24 {  
25     mat b(a.size(),vec(a.size()));  
26     for(ll i=0;i<a.size();i++)  
27         b[i][i]=1; 
28     while(n>0)  
29     {  
30         if(n & 1)  
31             b=mul(b,a);  
32         a=mul(a,a);  
33         n >>= 1;  
34     }  
35   
36     return b;  
37 }  
38 ll n;  
39 void solve()  
40 {  
41     mat a(2,vec(2));  
42     while(~scanf("%lld",&n) && n!=-1)  
43     {  
44         a[0][0]=1,a[0][1]=1;  
45         a[1][0]=1,a[1][1]=0;  
46         a=solve_pow(a,n);  
47         printf("%lld\n",a[1][0]);  
48     }  
49 }  
50 int main()  
51 {  
52     solve();  
53     return 0;  
54 }  

 

posted @ 2017-08-18 08:53  西北会法语  阅读(179)  评论(0编辑  收藏  举报