又見斐波那契~矩陣快速冪入門題


鏈接:https://www.nowcoder.com/acm/contest/105/G
來源:牛客網

題目描述

這是一個加強版的斐波那契數列。
給定遞推式
求F(n)的值,由於這個值可能太大,請對10 9+7取模。

輸入描述:

第一行是一個整數T(1 ≤ T ≤ 1000),表示樣例的個數。
以后每個樣例一行,是一個整數n(1 ≤ n ≤ 10
18
)。

輸出描述:

每個樣例輸出一行,一個整數,表示F(n) mod 1000000007。
示例1

輸入

4
1
2
3
100

輸出

1
16
57
558616258

這題是一題矩陣快速冪的模板題,表示第一次碰到矩陣快速冪然后就順便學一下,其實和快速冪差不多。
矩陣快速冪的難點一般是構造矩陣,但是這題遞推公式給了我們還是非常容易構造出矩陣的。
難題一般都是讓我們自己去推公式,然后再通過公式寫出所需要的矩陣。
遞推公式給了我們,
就是要找到一個矩陣A 【f(i),f(i-1),(i+1)^3,(i+1)^2,(i+1),1】 * A =【f(i-1),f(i-2),i^3,i^2,i,1】;
如果學過線代,這個是非常容易推出來的。
然后就通過矩陣的性質, F【n】=A^(n-1)*F【1】;
知道這些,就會發現這不就是一個SB題嗎

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <vector>
 4 #include <queue>
 5 #include <cstring>
 6 #include <string>
 7 using namespace std;
 8 const int maxn = 1e2 + 10;
 9 const int mod = 1e9 + 7;
10 typedef long long LL ;
11 struct mat
12 {
13     LL m[maxn][maxn];
14     mat() {
15        memset(m,0,sizeof(m));
16     }
17     mat operator * (mat &a ) {
18        mat ans;
19        for (int i=0 ;i<6 ;i++  ){
20           for (int j=0 ;j<6 ;j++) {
21               for (int k=0 ;k<6 ;k++) {
22                  ans.m[i][j]=(ans.m[i][j]+m[i][k]*a.m[k][j])%mod;
23               }
24           }
25        }
26        return ans;
27     }
28 };
29 mat modexp(mat a,LL b)
30 {
31     mat ans;
32     for (int i=0 ;i<6 ;i++ ) ans.m[i][i]=1;
33     while(b) {
34         if (b&1) ans=ans*a;
35         b=b>>1;
36         a=a*a;
37     }
38     return ans;
39 }
40 int main() {
41     long long  mm[6][6] = {
42         {1, 1, 1, 1, 1, 1},
43         {1, 0, 0, 0, 0, 0},
44         {0, 0, 1, 3, 3, 1},
45         {0, 0, 0, 1, 2, 1},
46         {0, 0, 0, 0, 1, 1},
47         {0, 0, 0, 0, 0, 1}
48     };
49     int t;
50     scanf("%d", &t);
51     while(t--) {
52         LL  n;
53         mat ans;
54         for (int i = 0 ; i < 6 ; i++) {
55             for (int j = 0 ; j < 6 ; j++) {
56                 ans.m[i][j] = mm[i][j];
57             }
58         }
59         scanf("%lld", &n);
60         ans = modexp(ans, n - 1);
61         printf("%lld\n", (ans.m[0][0] + ans.m[0][2] * 8 + ans.m[0][3] * 4 + ans.m[0][4] * 2 + ans.m[0][5]) % mod);
62     }
63     return 0;
64 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM