题意
T组数据,构造长度为的串,不含字串的方案数
数据范围:
分析
AC自动机构造矩阵,但我不会(目前)_(°:з」∠)_
可以将合法的三元串xyz看作xy->yz,这就形成了一个转移关系那么11->11就是非法的,13->32也是非法的
这就可以填充一个的矩阵,中元素表示从i转移到j的合法种数,所有元素和即为答案。
PS:比赛时丢脸的用trie树手写了一个的矩阵(把用111->11,21->213这种来表示转移),在线丢脸ε=ε=ε=ε=ε=ε=┌(; ̄◇ ̄)┘
#pragma GCC optimize(2)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <set>
#include <vector>
using namespace std;
using LL = long long;
const int MOD = 1e9 + 7;
struct matrix {
LL num[55][55], len;
void init(){
memset(num, 0, sizeof(num));
len = 0;
}
matrix operator *(const matrix &a){
matrix res;
res.init(), res.len = a.len;
for(int i = 0; i < len; i++)
for(int j = 0; j < len; j++)
for(int k = 0; k < len; k++)
res.num[i][j] += (num[i][k] * a.num[k][j]) % MOD, res.num[i][j] %= MOD;
return res;
}
void getprint(){
for(int i = 0; i < len; i++){
for(int j = 0; j < len; j++)
printf("%3lld ", num[i][j]);
printf("\n");
}
}
} A;
matrix qpow_matraix(matrix x, LL n);
LL T, N;
int main(){
A.init(), A.len = 9;
int i, j;
for(i = 0; i < 9; i++)
for(j = 0; j < 3; j++) A.num[i][j + i % 3 * 3] = 1;
A.num[0][0] = 0;//11->11
A.num[2][7] = 0;//13->32
A.num[4][4] = 0;//22->22
A.num[5][6] = 0;//23->31
A.num[6][2] = 0;//31->13
A.num[7][5] = 0;//32->23
A.num[8][8] = 0;//33->33
//A.getprint();
cin >> T;
while(T--){
cin >> N;
if(N == 1){cout << 3 << endl; continue;}
else if(N == 2){cout << 9 << endl; continue;}
LL ans = 0;
matrix tmp = qpow_matraix(A, N - 2);
for(i = 0; i < tmp.len; i++)
for(j = 0; j < tmp.len; j++) ans += tmp.num[i][j], ans %= MOD;
cout << ans << endl;
}
return 0;
}
matrix qpow_matraix(matrix X, LL n){
matrix E;
E.init(), E.len = X.len;
int i;
for(i = 0; i <= E.len; i++) E.num[i][i] = 1;
while(n){
if(n & 1) E = E * X;
X = X * X;
n >>= 1;
}
return E;
}