Loading

[记录] 生成函数习题

[YZOJ7198] 暴政之王

初始有一个 \(1,2,3\dots,n\) 的排列,再随机一个排列,将初始排列根据这个置换 \(m\) 次。

现在给出最终结果,问有多少排列可能是随机出的那个排列。

\(n\le 10^5,m\le10^9\),模数为 \(10^9+7\)

简要题解

[YZOJ7249] Curiosity

一个 \(K\) 面骰子扔 \(N\) 次,记 \(i\) 的出现次数为 \(a_i\),求:

\[E[\ \prod_{i=1}^La_i^F\ ] \]

\(0<N,K\le 10^9,0<F\le 1000,0<L\cdot F\le 50000,1\le L\le K\).

简要题解

[YZOJ7283] Counting

\(m\) 个格子,从左往右标号为 \(0, 1, . . . , m − 1\)

\(0\) 号格子出发,走 \(n\) 步,每步可以往左一格、原地不动、或者往右一格走一步,这个过程中不能走出格子

问有多少种方案可以回到 \(0\),答案对 \(998244353\) 取模。

\(1 ≤ n, m ≤ 10^7\).

首先把题意看作向前 \(0,1,2\) 格,最终走到第 \(n\) 格,避免往回走在组合意义上不好表示。

那么此时若没有不能走出格子的限制,\([x^n](1+x+x^2)^n\) 就是答案,然后 \((1+x+x^2)^n\) 其实是可以 \(O(n)\) 计算的。

\(H=1+x+x^2,F=H^n\),求导有 \(F'=n H^{n-1}H',F'H=nFH'\),然后可以根据这个等式一项项递推 \(F\)

至于不能走出格子的限制可以用双线翻转解决,每次要求的就是走 \(n\) 次到第 \(n+\Delta\) 格的方案数,\(\Delta\)\(n\) 同级。

查看代码
int main(){
	read(n), read(m);
	f[0] = inv[1] = 1;
	lfor(i, 2, 2 * n) inv[i] = (LL) Mod(-mod / i) * inv[mod % i] % mod;
	lfor(i, 0, 2 * n){
		// (If[i] + If[i - 1] + If[i - 2]) = n * (f[i] + 2 * f[i - 1])
		If[i] = (LL) n * Mod(F(i) + 2ll * F(i - 1) % mod - mod) % mod;
		MOD(If[i] -= IF(i - 1)), MOD(If[i] -= IF(i - 2));
		f[i + 1] = (LL) If[i] * inv[i + 1] % mod;
	}
	auto rev = [&](int &x, int &y, int b) -> void{ swap(x, y), x -= b, y += b; };
	auto calc = [&](int x, int y) -> int{ return abs(x - y) <= n ? f[n + (x - y)] : 0; };
	int Ans = calc(n, n), p, x, y;
	p = 1, x = n, y = n;
	while(x >= 0 && y >= 0){
		if(p) rev(x, y, 1), MOD(Ans -= calc(x, y));
		else rev(x, y, -m), MOD(Ans += calc(x, y) - mod);
		p ^= 1;
	}
	p = 0, x = n, y = n;
	while(x >= 0 && y >= 0){
		if(p) rev(x, y, 1), MOD(Ans += calc(x, y) - mod);
		else rev(x, y, -m), MOD(Ans -= calc(x, y));
		p ^= 1;
	}
	cout << Ans << endl;
	return 0;
}

[YZOJ7296] 师父

\(x,y\),初值都为 \(0\),然后进行 \(n\) 次操作。每次操作如下:

  • \(p\) 的概率,\(y\gets y+1,x\gets x+y\)
  • \(q\) 的概率,\(y\gets \min(y-1,0)\)

问最终 \(x\) 的期望。

\(n\le 10^7,p+q=1\)

\(H_i\) 表示第 \(i\)\(y\) 的期望值,故答案为 \(\sum_\limits{i=0}^{n-1}p\cdot(H_i+1)\).

考虑写出 \(H\) 的转移式

\[H_i=q\cdot (H_{i-1}-1)+p\cdot(H_{i-1}+1)+q\cdot P_{i-1} \]

\(P_i\) 含义是,进行 \(i\) 次操作后,\(y=0\) 的概率,因为 \(y\) 是不会变成 \(-1\) 的,所以要加回来处理边界。

于是考虑 \(P_i\) 的转移

\[P_i=q\cdot P_{i-1}+\sum_{j=0}^{i-2} p\cdot q\cdot P_j\cdot S_{i-j-2} \]

思路就是考虑上一次 \(y=0\) 是什么时候,然后乘上强制剩下一段都不能 \(y=0\) 的概率,也就是 \(S_i\) 的含义。

根据简单的组合数学知识,不难发现 \(S_{2i}={\rm Catalan}(i)\cdot (p\cdot q)^i\),所以可以写出 \(S(x)\) 的生成函数

\[S(x)=\frac{1-\sqrt{1-4pqx^2}}{2pqx^2} \]

然后让我们试图解出来 \(P(x)\) 的生成函数

\[\begin{aligned} P(x)&=qxP(x)+pqx^2P(x)S(x)+1\\ (1-qx-pqx^2S(x))P(x)&=1\\ (1-qx-pqx^2\frac{1-\sqrt{1-4pqx^2}}{2pqx^2})P(x)&=1\\ P(x)&=\frac{1}{1-qx-\frac{1-\sqrt{1-4pqx^2}}{2}}\\ P(x)&=\frac{2}{2-2qx-(1-\sqrt{1-4pqx^2})}\\ P(x)&=\frac{2}{1-2qx+\sqrt{1-4pqx^2}}\\ P(x)&=\frac{2(1-2qx-\sqrt{1-4pqx^2})}{(1-2qx+\sqrt{1-4pqx^2})(1-2qx-(\sqrt{1-4pqx^2})}\\ P(x)&=\frac{2(1-2qx-\sqrt{1-4pqx^2})}{(1-2qx)^2-(1-4pqx^2)}\\ P(x)&=\frac{1-2qx-\sqrt{1-4pqx^2}}{2qx(x-1)}\\ P(x)&=\frac{1}{1-x}(1+\frac{\sqrt{1-4pqx^2}-1}{2qx})\\ \end{aligned} \]

然后只要展开就好了

\[\begin{aligned} \text{[$x^{2n-1}$]}\frac{\sqrt{1-4pqx^2}-1}{2qx}&=-\frac{1}{q}[x^{2n}]\frac{\sqrt{1-4pqx^2}-1}{2}\\ &=-\frac{1}{q}[x^{n}]\frac{\sqrt{1-4pqx}-1}{2}\\ &=-p^nq^{n-1}{\rm Catalan}(n-1) \end{aligned} \]

查看代码
signed main(){
	read(n), read(p), read(q), prep(2 * n);
	P[0] = 1;
	lfor(i, 1, n / 2) P[i * 2 - 1] = Mod(-mul(pwp[i], mul(pwq[i - 1], Cat(i - 1))));
	lfor(i, 1, n) MOD(P[i] += P[i - 1] - mod);
	H[0] = 0;
	lfor(i, 1, n){
		H[i] = Mod(H[i - 1] - mul(2, q));
		MOD(H[i] += 1 + mul(q, P[i - 1]) - mod);
	}
	lfor(i, 0, n - 1) MOD(Ans += mul(p, H[i] + 1) - mod);
	cout << Ans << endl;
	return 0;
}
posted @ 2022-05-12 21:21  IrisT  阅读(65)  评论(0编辑  收藏  举报