时空限制 1000ms / 512MB
题目描述
定义一个串合法,当且仅当串只由A和B构成,且没有连续的3个A。P哥知道,密码就是长度为N的合法字符串数量对1926081719260817取模的结果。但是P哥不会算,所以他只能把N告诉你,让你来算
至于为什么要对这个数取模,好像是因为纪念某个人,但到底是谁,P哥也不记得了
然而他忘记字符串长度N应该是多少了,于是他准备试M组数据。
输入格式:
第一行给出一个整数M表示询问次数
接下来M行每行给出一个正整数N,表示该组询问中字符串的长度
输出格式:
对于每一次询问输出一行一个整数表示答案
说明
对于100%的数据,满足 n , m ≤ 5 ∗ 1 0 4 l ≤ r ≤ m k ≤ m x ≤ 2 31 − 1 n,m\leq 5*10^4\;\;\;l\leq r\leq m\;\;\;k\leq m\;\;\;x\leq 2^{31}-1 n,m≤5∗104l≤r≤mk≤mx≤231−1
题目分析
很久以前写的题了,最近突然发现变紫了。。。
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示当前字符串长度为
i
i
i,且末尾有连续
j
j
j个A的方案数
d
p
[
i
]
[
0
]
=
d
p
[
i
−
1
]
[
0
]
+
d
p
[
i
−
1
]
[
1
]
+
d
p
[
i
−
1
]
[
2
]
dp[i][0]=dp[i-1][0]+dp[i-1][1]+dp[i-1][2]
dp[i][0]=dp[i−1][0]+dp[i−1][1]+dp[i−1][2]
d
p
[
i
]
[
1
]
=
d
p
[
i
−
1
]
[
0
]
dp[i][1]=dp[i-1][0]
dp[i][1]=dp[i−1][0]
d
p
[
i
]
[
2
]
=
d
p
[
i
−
1
]
[
1
]
dp[i][2]=dp[i-1][1]
dp[i][2]=dp[i−1][1]
方程是线性的所以矩乘优化就好
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long lt;
#define lowbit(x) ((x)&(-x))
lt read()
{
lt f=1,x=0;
char ss=getchar();
while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}
while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}
return x*f;
}
const lt mod=19260817;
lt n,q;
struct matrix
{
lt mat[10][10],row,col;
matrix(int r=0,int c=0){
row=r; col=c;
for(int i=1;i<=row;++i)
for(int j=1;j<=col;++j)
mat[i][j]=0;
}
};
matrix operator *(matrix a,matrix b){
matrix c=matrix(a.row,b.col);
for(int i=1;i<=a.row;++i)
for(int j=1;j<=b.col;++j)
for(int k=1;k<=a.col;++k)
{
c.mat[i][j]+=a.mat[i][k]*b.mat[k][j]%mod;
c.mat[i][j]%=mod;
}
return c;
}
matrix qpow(matrix a,lt k)
{
matrix res=matrix(a.row,a.col);
for(int i=1;i<=a.row;++i) res.mat[i][i]=1;
while(k){
if(k&1) res=res*a;
a=a*a; k>>=1;
}
return res;
}
int main()
{
q=read();
matrix f=matrix(1,3),h=matrix(3,3);
f.mat[1][1]=f.mat[1][2]=1; f.mat[1][3]=0;
h.mat[1][1]=1; h.mat[1][2]=1; h.mat[1][3]=0;
h.mat[2][1]=1; h.mat[2][2]=0; h.mat[2][3]=1;
h.mat[3][1]=1; h.mat[3][2]=0; h.mat[3][3]=0;
while(q--)
{
n=read();
matrix res=f*qpow(h,n-1);
printf("%lld\n",(res.mat[1][1]+res.mat[1][2]+res.mat[1][3])%mod);
}
return 0;
}