6828. 【2020.10.25提高组模拟】幂
表达式由x,(,)
组成,一个合法的表达式为一个括号序中任意插入x。
求长度为\(n\)的合法表达式中x
的个数之和。
\(n\le 10^7\)
多组询问。
推了一个晚上的式子。。。
首先可以设\(f_n\)表示长度为\(n\)的表达式的方案数,\(g_n\)表示贡献和。
可以分别写出递推式,进而推出其生成函数:\(G(x)=\frac{\frac{1-x}{\sqrt{1-2x-3x^2}}-1}{2x}\)
发现重要的问题是求\((1-2x-3x^2)^{-\frac{1}{2}}\)。
考虑求出它的递推式。这里有个套路:设\(B(x)=A^k(x)\),两边求导得\(B'(x)=kA^{k-1}(x)A'(x)\),再乘\(A(x)\)得\(B'(x)A(x)=kB(x)A'(x)\)。把等式两边的第\(n\)位的系数表示出来,容易发现可以通过\(a_{0\dots n}\)和\(b_{0\dots n+1}\)推出\(a_{n+1}\)。于是可以写出个递推式。
然后就做完了。改题的时候直接抄了题解的式子,直接是答案的递推式。
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 10000000
#define ll long long
#define mo 998244353
int n;
ll inv[N+5],g[N+5];
int main(){
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
freopen("power.in","r",stdin);
freopen("power.out","w",stdout);
inv[1]=1;
for (int i=2;i<=N+1;++i)
inv[i]=(mo-mo/i)*inv[mo%i]%mo;
g[0]=0,g[1]=1,g[2]=2,g[3]=6;
for (int i=4;i<=N;++i)
g[i]=((3*i*g[i-1]+(i+3)*g[i-2]-(3*i-6)*g[i-3])%mo*inv[i+1]%mo+mo)%mo;
int T;
scanf("%d",&T);
while (T--){
scanf("%d",&n);
printf("%lld\n",g[n]);
}
return 0;
}