2018年湘潭大学程序设计竞赛 G又见斐波那契

题目描述 

这是一个加强版的斐波那契数列。
给定递推式
求F(n)的值,由于这个值可能太大,请对109+7取模。

输入描述:

第一行是一个整数T(1 ≤ T ≤ 1000),表示样例的个数。
以后每个样例一行,是一个整数n(1 ≤ n ≤ 1018)。

输出描述:

每个样例输出一行,一个整数,表示F(n) mod 1000000007。
示例1

输入

4
1
2
3
100

输出

1
16
57
558616258

一开始不了解矩阵快速幂,不知道怎么做,刷了一波矩阵快速幂再做这个就发现很简单了。

很明显就是6*6矩阵,构建好矩阵就行了。构建矩阵如下:

  fi        1    1    1    1    1    1    fi-1

 fi-1     1      0     0    0    0   0    fi-2

(i+1)3     0      0      1    3    3    1    i3

(i+1)2 =   0      0      0    1    2    1  *  i2

(i+1)      0      0      0    0    1    1    i

  1        0      0      0    0    0    1    1

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int mod = 1000000007;
 5 struct mat {
 6     ll m[6][6];
 7     mat() {
 8         memset(m, 0, sizeof(m));
 9     }
10 };
11 
12 mat mul(mat &A, mat &B) {
13     mat C;
14     for(int i = 0; i < 6; i ++) {
15         for(int j = 0; j < 6; j ++) {
16             for(int k = 0; k < 6; k ++) {
17                 C.m[i][j] = (C.m[i][j] + A.m[i][k]*B.m[k][j]) %mod;
18             }
19         }
20     }
21     return C;
22 }
23 
24 
25 mat pow(mat A, ll n) {
26     mat B;
27     for(int i = 0; i < 6; i ++) B.m[i][i] = 1;
28     while(n) {
29         if(n&1LL) B = mul(B, A);
30         A = mul(A, A);
31         n >>= 1;
32     }
33     return B;
34 }
35 int main() {
36     int t;
37     cin >> t;
38     mat A;
39     for(int i = 0; i < 6; i ++) A.m[0][i] = 1;
40     A.m[1][0] = A.m[2][2] = A.m[2][5] = 1;
41     A.m[3][3] = A.m[3][5] = A.m[4][4] = 1;
42     A.m[4][5] = A.m[5][5] = 1;
43     A.m[2][3] = A.m[2][4] = 3;
44     A.m[3][4] = 2;
45     while(t--) {
46         ll n;
47         cin >> n;
48         mat B =pow(A, n-1);
49         ll ans = B.m[0][0]+B.m[0][2]*8+B.m[0][3]*4+B.m[0][4]*2+B.m[0][5];
50         cout << ans%mod << endl;
51     }
52     return 0;
53 }

 

posted @ 2018-05-09 22:43  starry_sky  阅读(215)  评论(0编辑  收藏  举报