没错,就是一个板子。
够早的矩阵很简单:
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] ?
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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[N][N]; 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 }