HDU3117Fibonacci Numbers(矩阵快速幂 + 数学推导)

题目中有两种情况,分别是n <= 39和n > 39两种情况。

前一种只要打个表满足条件的时候直接输出就可以了。

对于后一种分别求前四位和后四位则需要一些前置知识,分别是对数运算和矩阵快速幂。

对于前一种,贴一张推导公式,原链接:https://www.cnblogs.com/Blogggggg/p/7356668.html

这样就能求出前四位,对于后四位,则需要算出第n项斐波那契数列的值,然后取余运算。

 于是有以下代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 using namespace std;
 7 const int MAXN = 2;
 8 typedef long long LL;
 9 LL fib[45];
10 void init(){
11     fib[1] = 1;
12     for(int i = 2; i <= 40; i ++)
13         fib[i] = fib[i - 1] + fib[i - 2];
14 }
15 struct Matrix{
16     LL m[MAXN][MAXN];
17     Matrix(){
18         memset(m, 0, sizeof(m));
19     }
20 };
21 int find_head(int n){
22     double t = -0.5 * log10(5.0) + n * log10((1 + pow(5, 0.5)) / 2);
23     t -= floor(t);
24     double temp = pow(10.0, t + 3);
25     return int(temp);
26 }
27 Matrix multi(Matrix a, Matrix b){
28     Matrix res;
29     memset(res.m, 0, sizeof(res.m));
30     for(int i = 0; i < MAXN; i ++)
31         for(int j = 0; j < MAXN; j ++)
32             for(int k = 0; k < MAXN; k ++)
33                 res.m[i][j] += (a.m[i][k] * b.m[k][j] % 10000);
34     return res;
35 }
36 Matrix last(Matrix a, int n){
37     Matrix res;
38     memset(res.m, 0, sizeof(res.m));
39     for(int i = 0; i < 2; i++)
40         res.m[i][i] = 1;
41     while(n){
42         if(n & 1)
43             res = multi(res, a);
44         a = multi(a, a);
45         n >>= 1;
46     }
47     return res;
48 }
49 int main(){
50     init();
51     LL n;
52     while(cin >> n){
53         if(n <= 39)
54             cout << fib[n] << endl;
55         else{
56             Matrix ori;
57             ori.m[1][1] = ori.m[0][1] = ori.m[1][0] = 1;
58             ori.m[0][0] = 0;
59             printf("%04d....%04d\n",find_head(n), last(ori, n - 1).m[0][0] % 10000);
60         }
61     }
62     return 0;
63 }

猜你喜欢

转载自www.cnblogs.com/pureayu/p/12721430.html