湘潭校赛——又见斐波那契(矩阵快速幂)

题目链接:https://www.nowcoder.com/acm/contest/105/G

思路:这题一看数据范围就知道是个矩阵快速幂,通过构造矩阵知我们需要的转移矩阵为下图形式,不过需要特判1然后输出的是n-1的结果哦,因为这个我本题WA了==!矩阵快速幂最难得就是构造矩阵,当矩阵构造出来之后基本上就好做了~

 1 #include <cstdio>
 2 #include <cstring>
 3 
 4 typedef long long ll;
 5 const int mod = 1e9 + 7;
 6 
 7 int t;
 8 ll n;
 9 
10 void mul(int f[6], int a[6][6]) {
11     int c[6];
12     memset(c, 0, sizeof(c));
13     for(int i = 0; i < 6; i++) {
14         for(int j = 0; j < 6; j++) {
15             c[i] = (c[i] + (ll)f[j] * a[j][i] % mod) % mod;
16         }
17     }
18     memcpy(f, c, sizeof(c));
19 }
20 
21 void mulself(int a[6][6]) {
22     int c[6][6];
23     memset(c, 0, sizeof(c));
24     for(int i = 0; i < 6; i++) {
25         for(int j = 0; j < 6; j++) {
26             for(int k = 0; k < 6; k++) {
27                 c[i][j] = (c[i][j] + (ll) a[i][k] * a[k][j] % mod) % mod;
28             }
29         }
30     }
31     memcpy(a, c, sizeof(c));
32 }
33 
34 int main() {
35     scanf("%d", &t);
36     while(t--) {
37         int f[6] = {1, 0, 1, 1, 1, 1};
38         int a[6][6] = {{1, 1, 0, 0, 0, 0}, {1, 0, 0, 0, 0, 0}, {1, 0, 1, 0, 0, 0}, {4, 0, 3, 1, 0, 0}, {6, 0, 3, 2, 1, 0}, {4, 0, 1, 1, 1, 1}};
39         scanf("%lld", &n);
40         n = n - 1;
41         for(; n; n >>= 1) {
42             if(n & 1)
43                 mul(f, a);
44             mulself(a);
45         }
46         printf("%d\n", f[0]);
47     }
48     return 0;
49 }

 

 

代码实现如下:

 

posted @ 2018-04-27 17:30  Dillonh  阅读(177)  评论(0编辑  收藏  举报