- 当满足素数2和素数3的条件后,下一个素数区间5乃至之后的都会被满足。
- 考虑能否从f[n - 1]转换到f[n],考虑第i - 1位,如果后面加红色一定满足条件,所以f[n]先是加上f[n - 1]
- 如果最后加蓝色,上一位一定是红色,且上上位也得是红色
- 所以f[n] = f[n - 1] + f[n - 3]
- n的范围太大,所以无法将递推的结果保存起来,所以矩阵快速幂
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const int N = 3;
const ll mod = 1e9 + 7;
ll n;
void mul(ll c[], ll a[], ll b[][N])
{
ll temp[N] = {0};
for (int i = 0; i < N; i ++ )
for (int j = 0; j < N; j ++ )
temp[i] = (temp[i] + a[j] * b[j][i] % mod) % mod;
memcpy(c, temp, sizeof temp);
}
void mul(ll c[][N], ll a[][N], ll b[][N])
{
ll temp[N][N] = {0};
for (int i = 0; i < N; i ++ )
for (int j = 0; j < N; j ++ )
for (int k = 0; k < N; k ++ )
temp[i][j] = (temp[i][j] + a[i][k] * b[k][j] % mod) % mod;
memcpy(c, temp, sizeof temp);
}
int main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int _;
cin >> _;
while (_ -- )
{
cin >> n;
if (n == 2)
{
cout << 3 << endl;
continue;
}
if (n == 3)
{
cout << 4 << endl;
continue;
}
n -= 3;
ll f1[N] = {4, 3, 2};
ll a[N][N] = {
{1, 1, 0},
{0, 0, 1},
{1, 0, 0}
};
while (n)
{
if (n & 1) mul(f1, f1, a);
mul(a, a, a);
n >>= 1;
}
cout << f1[0] % mod << endl;
}
return 0;
}