20250610 闲话

某题转化后得到:

初始有 \(n\) 个孤立点。\(n - 1\) 次操作,每次合并两个连通块。每次操作之后询问:

在每个连通块中至多取 \(1\) 个点,总共恰好取 \(m\) 个点,求取法的方案数。

\(2 \le n \le 10^5, 2\le m \le 10\)。答案对 \(998244353\) 取模。


设当前有 \(k\) 个连通块,第 \(i\) 个大小为 \(s_i\),相当于动态求 \([x^m]\prod_{i=1}^k(1+s_ix)\)

直接在线段树上插入或删除,pushup 暴力卷积合并信息,\(O(nm^2\log n)\)

容易 \(O(m)\) 加入一个 \((1+ax)\),使用线段树分治可以 \(O(nm\log n)\)

\[f'(x) = f(x) + s_if(x-1) \]

观察发现删去一个 \((1+ax)\) 可以把加入的过程逆过来做(相当于交换插入顺序然后撤销),也是 \(O(m)\) 的,于是 \(O(nm)\)前面两种做法都蠢了。

upd 20250611:

事实上:

\[\frac{1}{1+ax} = \sum_{i=0}^{\infty} (-1)^i a^i x^i \]

一个系数为 \(a\) 的 0-1 背包物品的逆,是一个系数为 \(-a\),重量相同的完全背包物品。

void ins(LL x) { for (int i = m; i; --i) Fplus(f[i], f[i - 1] * x % mod); }
void ers(LL x) { for (int i = 1; i <= m; ++i) Fminus(f[i], f[i - 1] * x % mod); }
posted @ 2025-06-10 18:10  SZwinsun  阅读(13)  评论(0)    收藏  举报