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

推一推矩阵直接快速幂。

 1 #include<bits/stdc++.h>
 2 #define LL long long
 3 #define pii pair<int,int>
 4 #define mk make_pair
 5 #define fi first
 6 #define se second
 7 using namespace std;
 8 
 9 const int N=1e5+7;
10 const int M=1e5+7;
11 const int inf=0x3f3f3f3f;
12 const LL INF=0x3f3f3f3f3f3f3f3f;
13 const int mod=1e9+7;
14 
15 LL n;
16 struct Matrix {
17     LL a[6][6];
18     Matrix() {memset(a, 0, sizeof(a));}
19     void init() {
20         for(int i = 0; i < 6; i++)
21             for(int j = 0; j < 6; j++)
22                 a[i][j] = (i == j);
23     }
24 
25     Matrix operator * (const Matrix &B) const {
26         Matrix C;
27         for(int i = 0; i < 6; i++) {
28             for(int j = 0; j < 6; j++) {
29                 for(int k = 0; k < 6; k++) {
30                     C.a[i][j] = (C.a[i][j] + a[i][k] * B.a[k][j]) % mod;
31                 }
32             }
33         }
34         return C;
35     }
36 
37     Matrix operator ^ (const LL &p) const {
38         Matrix A =  *this, res;
39         res.init();
40         LL t = p;
41         while(t) {
42             if(t & 1) res = res * A;
43             A = A * A; t >>= 1;
44         }
45         return res;
46     }
47 }A;
48 
49 
50 int main() {
51 
52     int a[6][6] = {
53         {1, 1, 1, 1, 1, 1},
54         {1, 0, 0, 0, 0, 0},
55         {0, 0, 1, 3, 3, 1},
56         {0, 0, 0, 1, 2, 1},
57         {0, 0, 0, 0, 1, 1},
58         {0, 0, 0, 0, 0, 1}
59     };
60 
61     for(int i = 0; i < 6; i++)
62         for(int j = 0; j < 6; j++)
63             A.a[i][j] = a[i][j];
64 
65     int T; scanf("%d", &T);
66     while(T--) {
67         scanf("%lld", &n);
68         if(n == 1) {
69             puts("1");
70             continue;
71         }
72         Matrix B = A ^ (n - 1);
73         LL ans = B.a[0][0] + B.a[0][2] * 8 + B.a[0][3] * 4 + B.a[0][4] * 2 + B.a[0][5];
74         ans %= mod;
75         printf("%lld\n", ans);
76     }
77     return 0;
78 }
79 /*
80 */

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/8985606.html