Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1146 Accepted Submission(s): 491
php
若是用a表示紅色,用b表示藍色。題意明顯能夠看出只須要管長度2和3的連續序列是否符合!ios
若是以b結尾,那麼下一個必須是a,或者加個aab就能夠了!app
先看這個特徵方程F[i] = F[i - 1] + F[i - 3],那麼就有一個矩陣以下less
咱們的目標矩陣就是ui
那麼,針對這個矩陣咱們如何轉置呢?spa
先看目標矩陣第一個:F[i]設計
F[i] = F[i - 1] + F[i - 3]code
那麼,由矩陣乘法,轉置矩陣第一行,彷佛就定了:1 0 1blog
一樣的,二三行就是1 0 0 和 0 1 0ip
整個矩陣以下:
#include<iostream> #include<algorithm> #include<cmath> #include<cstdio> #include<cstring> #define INF 0x3f3f3f3f #define mod 1000000007 using namespace std; typedef long long ll; const int maxn = 100010; ll n; struct Matrix { ll a[5][5]; }; Matrix mul(Matrix x, Matrix y) { Matrix temp; for (int i = 1; i <= 3; i++) for (int j = 1; j <= 3; j++) temp.a[i][j] = 0; for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 3; j++) { ll sum = 0; for (int k = 1; k <= 3; k++) { sum = (sum + x.a[i][k] * y.a[k][j] % mod) % mod; } temp.a[i][j] = sum; } } return temp; } Matrix quickpow(Matrix A,ll k) { Matrix res; res.a[1][1] = 1; res.a[1][2] = 0; res.a[1][3] = 0; res.a[2][1] = 0; res.a[2][2] = 1; res.a[2][3] = 0; res.a[3][1] = 0; res.a[3][2] = 0; res.a[3][3] = 1; while (k) { if (k & 1) res = mul(res, A); A = mul(A, A); k >>= 1; } return res; } int main() { int t; scanf("%d", &t); while (t--) { scanf("%lld", &n); if (n == 2) { printf("3\n"); continue; } Matrix A; A.a[1][1] = 1; A.a[1][2] = 0; A.a[1][3] = 1; A.a[2][1] = 1; A.a[2][2] = 0; A.a[2][3] = 0; A.a[3][1] = 0; A.a[3][2] = 1; A.a[3][3] = 0; Matrix res = quickpow(A, n - 2); ll x = (res.a[1][1] + res.a[1][2] + res.a[1][3]) % mod; ll y = (res.a[2][1] + res.a[2][2] + res.a[2][3]) % mod; ll z = (res.a[3][1] + res.a[3][2] + res.a[3][3]) % mod; printf("%lld\n", (x + y + z) % mod); } }