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;
}
posted @ 2020-10-26 22:16  jz_597  阅读(150)  评论(0编辑  收藏  举报