HDU3117Fibonacci Numbers (matrix fast power + mathematical derivation)

 

There are two cases in the title, which are n <= 39 and n> 39.

In the former case, it is only necessary to output directly when a table is satisfied.

For the latter, finding the first four digits and the last four digits requires some pre-knowledge, which are logarithmic operations and matrix fast power, respectively.

For the former, post a derivation formula, the original link: https://www.cnblogs.com/Blogggggg/p/7356668.html

 

In this way, the first four digits can be found. For the last four digits, you need to calculate the value of the n-th Fibonacci sequence, and then take the remainder operation.

 

 So there is the following code:

 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 }

 

Guess you like

Origin www.cnblogs.com/pureayu/p/12721430.html