解题思路:
容易发现
fi=fi−1+2fi−2+1=2fi−1+(i%2)
f
i
=
f
i
−
1
+
2
f
i
−
2
+
1
=
2
f
i
−
1
+
(
i
%
2
)
,但还不够。
又发现
fi=⌊2i+13⌋
f
i
=
⌊
2
i
+
1
3
⌋
,直接FFT+高精度即可。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int getint()
{
int i=0,f=1;char c;
for(c=getchar();(c!='-')&&(c<'0'||c>'9');c=getchar());
if(c=='-')c=getchar(),f=-1;
for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
return i*f;
}
const int N=100005,mod=998244353,g=3;
ll Pow(ll x,int y)
{
ll res=1;
for(;y;y>>=1,x=x*x%mod)
if(y&1)res=res*x%mod;
return res;
}
ll w[N],w_inv[N],pos[N];
struct Bignum
{
ll a[N],deg;
inline void clear(){for(int i=0;i<=deg;i++)a[i]=0;deg=0;}
inline void copy(const Bignum &A)
{
clear();deg=A.deg;
for(int i=0;i<=deg;i++)a[i]=A.a[i];
}
inline void W(){for(int i=deg;i>=0;i--)putchar('0'+a[i]);}
}A,B,C,D,res,res1;
void NTT(ll *f,int len,int on)
{
for(int i=1;i<len;i++)
pos[i]=(i&1)?pos[i>>1]>>1|(len>>1):pos[i>>1]>>1;
for(int i=1;i<len;i++)
if(i<pos[i])swap(f[i],f[pos[i]]);
for(int i=1,num=1;i<len;i<<=1,num++)
{
ll wi=(on==1?w[num]:w_inv[num]);
for(int j=0;j<len;j+=(i<<1))
{
ll wn=1;
for(int k=j;k<j+i;k++)
{
ll u=f[k],v=wn*f[k+i]%mod;
f[k]=(u+v)%mod,f[k+i]=(u-v+mod)%mod;
wn=wn*wi%mod;
}
}
}
if(on==-1)
for(int i=0,inv=Pow(len,mod-2);i<len;i++)
f[i]=f[i]*inv%mod;
}
inline Bignum operator * (const Bignum &A,const Bignum &B)
{
C.copy(A),D.copy(B);
res.clear();res.deg=C.deg+D.deg;
int len=1;
while(len<=C.deg+D.deg)len<<=1;
NTT(C.a,len,1),NTT(D.a,len,1);
for(int i=0;i<len;i++)C.a[i]*=D.a[i];
NTT(C.a,len,-1);
for(int i=0;i<=res.deg;i++)res.a[i]=C.a[i];
for(int i=0;i<len;i++)C.a[i]=D.a[i]=0;
for(int i=0;i<=res.deg;i++)if(res.a[i]>=10)res.a[i+1]+=res.a[i]/10,res.a[i]%=10;
while(res.a[res.deg+1])
{
int i=++res.deg;
if(res.a[i]>=10)res.a[i+1]+=res.a[i]/10,res.a[i]%=10;
}
return res;
}
inline Bignum Pow(const Bignum &A,int b)
{
res1.clear(),res1.a[0]=1,B.copy(A);
for(;b;b>>=1,B=B*B)
if(b&1)res1=res1*B;
return res1;
}
inline Bignum operator /(const Bignum &A,int b)
{
res.clear(),C.copy(A),res.deg=C.deg;
for(int i=C.deg,ret=C.a[i];i>=0;i--)
{
res.a[i]=ret/b;
if(i)ret=(ret-res.a[i]*b)*10+C.a[i-1];
}
while(!res.a[res.deg])res.deg--;
return res;
}
void solve(int n)
{
A.clear();A.a[0]=2;
A=Pow(A,n+1);
A=A/3;
A.W(),putchar('\n');
}
int main()
{
//freopen("baguenaudier.in","r",stdin);
//freopen("baguenaudier.out","w",stdout);
int len=1,num=0;
while(len<=N+N)
{
len<<=1;
w[++num]=Pow(g,(mod-1)/len);
w_inv[num]=Pow(w[num],mod-2);
}
for(int T=getint();T;T--)
solve(getint());
return 0;
}