闲话 23.2.10

闲话

rushcheyo 老师的题好神……
反转了
T1 是贪心也能做的博弈论
T2 是 2e5 但放过 \(O(n\sqrt n\log n)\) 做法的 \(O(n\sqrt n)\) 难调分块
T3 是 atc world tour final 2019 最后一题(gtm:《概率密度扩充状态》)
我不好说是 rushcheyo 的问题还是我们的问题了

今日推歌:白金 disco 白金打吊针

化学题(?)

前置知识:符号化

烷基计数

计数 \(n\) 个点、每个点度数 \(\le 4\) 且根的度数 \(\le 3\) 的无标号有根树。

\(\mathcal T\) 为答案的组合类,我们能写出

\[\mathcal T = \mathcal Z \times \text{MSET}_3(\mathcal T) + \mathcal E \]

也就是

\[T(z) = z\left(\frac{T(z)^3}{6} + \frac{T(z)T(z^2)}{2} + \frac{T(z^3)}{3}\right) + 1 \]

我们可以应用牛顿迭代来做这个。设

\[G(T(z)) = z\left(\frac{T(z)^3}{6} + \frac{T(z)T(z^2)}{2} + \frac{T(z^3)}{3}\right) - T(z) + 1 = 0 \]

由于我们希望从 \(z^n\) 的截取得到 \(z^{2n}\) 的截取,我们相当于已知了 \(\forall k > 1, \ T(z^k)\),因此不妨将式子中的 \(T(z^k)\) 视作常数,记为 \(C_k\)。也就有

\[G(x) = z\left(\frac{x^3}{6} + \frac{C_2x}{2} + \frac{C_3}{3}\right) - x + 1 \]

从而

\[G'(x) = z\left(\frac{x^2}{2} + \frac{C_2}{2}\right) - 1 \]

记已经得到的截取为 \(T^*(z)\),我们有

\[T(z) = T^*(z) - \frac{z\left(T^*(z)^3 + 3C_2T^*(z) + 2C_3\right) - 6T^*(z) + 6}{z\left(3T^*(z)^2 + 3C_2\right) - 6} \]

直接作即可。总时间复杂度 \(O(n\log n)\)

Submission.

code
poly newton(int n) {
    poly F(1, 1), A, B;
    for (int k = 2; k < (n << 1); k <<= 1) {
        F.resize(k);
        A = F.shiftvar(2), B = F.shiftvar(3);
        F = F - (((F * F * F + 3 * A * F + 2 * B) >> 1) - 6 * F + 6) * (3 * (( F * F + A ) >> 1) - 6).inv().resize(k);
    } return F;
}



烯烃计数

计数 \(n\) 个碳的烯烃(\(\text{C}_n\text{H}_{2n}\))。

这个东西不太好形式化啊……
断开碳-碳双键后,两边是根节点度数不超过 \(2\) 的无标号有根树,这个树的根节点下面是两个烷基。

设烷基的组合类是 \(\mathcal T\),我们可以直接写出这种无标号有根树的组合类 \(\mathcal P\)

\[\mathcal P = \mathcal Z\times \text{MSET}_2(\mathcal T) \]

然后就很简单了,我们直接对 \(\mathcal P\) 做一下 \(\text{MSET}_2\) 就是答案。

Submission.

code
poly MSET(poly F, int cnt) {
	if (cnt == 1) return F;
	if (cnt == 2) return ginv(2) * ( (F * F).split(F.degree()) + F.shiftvar(2) );
	if (cnt == 3) {
		poly F2 = (F * F).split(F.degree()), FS2 = F.shiftvar(2);
		return ginv(6) * ( F2 * F ).split(F.degree()) + ginv(2) * (F * FS2).split(F.degree()) + ginv(3) * F.shiftvar(3);
	} 
	if (cnt == 4) {
		poly F2 = (F * F).split(F.degree()), FS2 = F.shiftvar(2);
		return ginv(24) * (F2 * F2).split(F.degree()) + ginv(4) * (F2 * FS2).split(F.degree()) + ginv(3) * (F * F.shiftvar(3)).split(F.degree()) + ginv(8) * (FS2 * FS2).split(F.degree()) + ginv(4) * F.shiftvar(4);
	}
}

signed main() {
    cin >> n; 
	poly A = newton(n);
	poly P = MSET(A, 2) >> 1;
	poly Q = MSET(P, 2);
	rep(i,2,n) cout << Q[i] << '\n';
} 



烷烃计数

计数 \(n\) 个点、每个点度数 \(\le 4\) 的无标号无根树。

首先有神奇结论:
无标号无根树不是很好计数,考虑钦定一些东西的情况。我们设一棵无标号无根树在钦定一个点为根时被计数了 \(p\) 次,钦定一条边为根时被计数了 \(q\) 次,钦定计数重心时被计数了 \(s = [重心为两个]\) 次,则 \(p - q + s = 1\)
证明其实不难。\(s = 0\) 时钦定边其实等于钦定了一个端点,需要这些端点彼此不同。容易发现被计数了 \(n - (n - 1) + 0 = 1\) 次。\(s = 1\) 时更好说了,这重心肯定是一条边的两个端点,这俩端点彼此等价,因此被计数了 \((n - 1) - (n - 1) + 1 = 1\) 次。

仍然假设上面的烷基的组合类是 \(\mathcal T\),上面钦定三种信息时对应的组合类是 \(\mathcal {P, Q, S}\),则有

\[\mathcal P = \mathcal Z\times \text{MSET}_4(\mathcal T) \qquad \mathcal Q = (\mathcal T - \mathcal E)^2 / \textbf G \qquad \mathcal S = \text{AMP}_2(\mathcal T) \]

容易翻译成 GF。

解释:(为涵盖更多解法,这写的是题解做法)
\(\mathcal P\) 繁而不难,略去。\(\mathcal S\) 是 Amplification 构造,翻译就是 \(T(z^2)\),性质显然。
对于 \(\mathcal Q\),我们需要考虑将两棵树用一条边 \(-\) 拼合。我们设元素 \(a\in Q\) 可以被拆解为 \(\{t, -, t'\}\),其中 \(t, t' \in \mathcal T\),为 \(a\) 的两棵子树;并记 \(a = (t, t')\)。则我们定义一个等价关系 \(\textbf G\)

\[a_1\textbf G a_2 \iff (t_1 = t_2 \land t'_1 = t'_2) \ \lor \ (t_1 = t'_2 \land t'_1 = t_2) \]

也就是子树相同但是顺序不同的树在同一等价类中。我们可以自然写出

\[\mathcal Q = (\mathcal T - \mathcal E)^2 / \textbf G \]

然后考虑翻译成生成函数的形式。我们可以发现,对于两棵子树不同的元素,其在乘方时被计数了两次,因此除以 \(2\) 即可;而两棵子树相同的元素只被计数了一次,我们可以加入这一部分元素,随后整体除以 \(2\)。加入的内容可以被符号化地写作 \(\text{AMP}_2(\mathcal T) - \mathcal E\):新组合类里没有空元素,需要减去。也就是

\[Q(z) = \frac{(T(z) - 1)^2 + T(z^2) - 1}{2} \]

最后 \(\mathcal P - \mathcal Q +\mathcal S\) 就是答案的组合类。

Submission.

code
signed main() {
    cin >> n;
	poly A = newton(n);
	poly F = "x"_p * MSET(A, 4) - ginv(2) * (((A - 1) * (A - 1)).split(n) + A.shiftvar(2) - 1) + A.shiftvar(2);
	cout << F[n] << '\n';
} 
posted @ 2023-02-10 14:13  joke3579  阅读(118)  评论(4编辑  收藏  举报