您的位置:首页 > 其它

luogu P1939 【模板】矩阵加速(数列)

2018-11-11 20:11 387 查看

嘟嘟嘟

 

没错,就是一个板子。

够早的矩阵很简单:

1 0 1

1 0 0

0 1 0

然后我们把这个矩阵快速幂乘n - 3次后,a[0][0] + a[0][1] + a[0][2]就是答案。

然而我刚开始一直把a[0][0] + a[0][2]当成答案,所以一直不对。因为递推式是这么给的,我就觉得n和n - 2没有关系。但是在矩阵上,n就应该等于转移矩阵的第一行乘以刚开始的矩阵(就是一列1 1 1)的第一列。

这样就可以推断,如果快速幂乘n - 2次后,答案应该是a[1][0] + a[1][1] + a[1][2]。

然而我没弄懂的是:乘n次后,答案为啥是a[1][0] ?

1 #include<cstdio>
2 #include<iostream>
3 #include<cmath>
4 #include<algorithm>
5 #include<cstring>
6 #include<cstdlib>
7 #include<cctype>
8 #include<vector>
9 #include<stack>
10 #include<queue>
11 using namespace std;
12 #define enter puts("")
13 #define space putchar(' ')
14 #define Mem(a, x) memset(a, x, sizeof(a))
15 #define rg register
16 typedef long long ll;
17 typedef double db;
18 const int INF = 0x3f3f3f3f;
19 const db eps = 1e-8;
20 //const int maxn = ;
21 const ll mod = 1e9 + 7;
22 inline ll read()
23 {
24     ll ans = 0;
25     char ch = getchar(), last = ' ';
26     while(!isdigit(ch)) {last = ch; ch = getchar();}
27     while(isdigit(ch)) {ans = (ans << 1) + (ans << 3) + ch - '0'; ch = getchar();}
28     if(last == '-') ans = -ans;
29     return ans;
30 }
31 inline void write(ll x)
32 {
33     if(x < 0) x = -x, putchar('-');
34     if(x >= 10) write(x / 10);
35     putchar(x % 10 + '0');
36 }
37
38 const int N = 3;
39 struct Mat
40 {
41     ll a

;
42     Mat operator * (const Mat& oth)const
43     {
44         Mat ret; Mem(ret.a, 0);
45         for(int i = 0; i < N; ++i)
46             for(int j = 0; j < N; ++j)
47                 for(int k = 0; k < N; ++k)
48                     ret.a[i][j] += a[i][k] * oth.a[k][j], ret.a[i][j] %= mod;
49         return ret;
50     }
51 }f;
52 void init()
53 {
54     Mem(f.a, 0);
55     f.a[0][0] = f.a[0][2] = 1;
56     f.a[1][0] = f.a[2][1] = f.a[3][2] = 1;
57 }
58
59 Mat quickpow(Mat A, ll b)
60 {
61     Mat ret; Mem(ret.a, 0);
62     for(int i = 0; i < N; ++i) ret.a[i][i] = 1;
63     for(; b; b >>= 1, A = A * A)
64         if(b & 1) ret = ret * A;
65     return ret;
66 }
67
68 int main()
69 {
70
71     int T = read();
72     init();
73     while(T--)
74     {
75         int n = read();
76         if(n < 4) {puts("1"); continue;}
77         n -= 3;
78         Mat A = quickpow(f, n);
79         write((A.a[0][0] + A.a[0][1] + A.a[0][2]) % mod), enter;
80     }
81     return 0;
82 }
View Code

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: