6828. 【2020.10.25提高组模拟】幂

表达式由x,(,)组成,一个合法的表达式为一个括号序中任意插入x。

求长度为(n)的合法表达式中x的个数之和。

(nle 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_{0dots n})(b_{0dots 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
",g[n]);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/jz-597/p/13881728.html