前往:我自己搭建的博客
题目
题解
对于n<=1e7的数据,可以使用常规的动态规划。用f[i][0/1/2]分别表示长度为i,且以AA/A/B结尾的字符串的数量。可以得到状态转移方程:
f[i][0]=f[i-1][1] , f[i][1]=f[i-1][2] , f[i][2]=f[i-1][0]+f[i-1][1]+f[i-1][2]
对于大数据,使用矩阵优化。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD=19260817;
int n;
struct matrix{ll s[5][5];}st,nxt;
inline matrix mul(matrix a,matrix b)
{
matrix c; memset(c.s,0,sizeof(c.s));
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
for(int k=1;k<=3;k++)
c.s[i][j]=(c.s[i][j]+a.s[i][k]*b.s[k][j]%MOD)%MOD;
return c;
}
inline matrix quick_pow(matrix a,ll b)
{
matrix c;
for(int i=1;i<=3;i++)for(int j=1;j<=3;j++) c.s[i][j]=(i==j);
for( ;b;b>>=1)
{
if(b&1) c=mul(c,a);
a=mul(a,a);
}
return c;
}
inline void pre()
{
st.s[1][1]=0;st.s[2][1]=1;st.s[3][1]=1;
nxt.s[1][1]=0;nxt.s[1][2]=1;nxt.s[1][3]=0;
nxt.s[2][1]=0;nxt.s[2][2]=0;nxt.s[2][3]=1;
nxt.s[3][1]=1;nxt.s[3][2]=1;nxt.s[3][3]=1;
}
inline void solve()
{
pre(); nxt=quick_pow(nxt,n-1);
st=mul(nxt,st);
ll ans=(st.s[1][1]+st.s[2][1]+st.s[3][1])%MOD;
printf("%lld\n",ans);
}
int main()
{
int T; scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
solve();
}
return 0;
}