清华集训2017 D1T1 生成树计数
n ≤ 30000 n\le30000 n≤30000 个块分别含 a i a_i ai 个点,度数 d i d_i di 造成权值 v a l ( d ) = ( ∏ i = 1 n d i m ) ( ∑ i = 1 n d i m ) val(d) = (\prod_{i=1}^n d_i^m ) (\sum_{i=1}^n d_i^m) val(d)=(∏i=1ndim)(∑i=1ndim)。求所有生成树的权值和。
先不考虑后面那个 ∑ \sum ∑,那么可以表示为若干个 w ( d i ) = d i m w(d_i)=d_i^m w(di)=dim 的积。
用 egf 分配 prufer 序列的位置,若第 i i i 个块分到 c i c_i ci 个位置,那么其度数为 d i = c i + 1 d_i=c_i+1 di=ci+1。并且要为每个度数决定连接哪个点,即 a i c i + 1 a_i^{c_i+1} aici+1。
( ∏ a i ) ∑ ∑ c i = n − 2 ( n − 2 ) ! ∏ c i ! ∏ a i c i w ( c i + 1 ) (\prod a_i)\sum_{\sum c_i=n-2}\frac{(n-2)!}{\prod c_i!}\prod a_i^{c_i}w(c_i+1) (∏ai)∑ci=n−2∑∏ci!(n−2)!∏aiciw(ci+1)
这里把公因子 ( ∏ a i ) (\prod a_i) (∏ai) 提到了前面。 ( n − 2 ) ! ∏ c i ! \frac{(n-2)!}{\prod c_i!} ∏ci!(n−2)! 是分配位置,用 egf 搞掉。
那么块 i i i 的 egf F i ( x ) = ∑ x k k ! a i k w ( k + 1 ) F_i(x) = \sum\frac{x^k}{k!} a_i^k w(k+1) Fi(x)=∑k!xkaikw(k+1) 【不要漏写+1】
可以发现如果设 F ( x ) = ∑ x k k ! w ( k + 1 ) F(x) = \sum\frac{x^k}{k!} w(k+1) F(x)=∑k!xkw(k+1),那么 F i ( x ) = F ( a i x ) F_i(x)=F(a_ix) Fi(x)=F(aix)
把每块的 egf 乘起来 a n s w e r = ( ∏ a i ) ( n − 2 ) ! [ x n − 2 ] ∏ F ( a i x ) answer = (\prod a_i)(n-2)![x^{n-2}]\prod F(a_ix) answer=(∏ai)(n−2)![xn−2]∏F(aix)
以上推理只要树权值满足 ∏ w ( d i ) \prod w(d_i) ∏w(di) 的形式即可进行
考虑一个简单的子程序:给一个 t t t 次多项式 P P P 和 n n n 个数 a i a_i ai,求 ∑ P ( a i x ) \sum P(a_ix) ∑P(aix)
若 P = ∑ p k x k P=\sum p_kx^k P=∑pkxk 那么 ∑ P ( a i x ) = ∑ p k ∑ i a i k x k \sum P(a_ix)=\sum p_k\sum_ia_i^kx^k ∑P(aix)=∑pk∑iaikxk
先求 a i a_i ai 的 0 ∼ t 0\sim t 0∼t 次等幂和 ∑ i = 1 n a i k \sum_{i=1}^na_i^k ∑i=1naik,然后与 P P P 的系数对位相乘即可。
等幂和用 ∑ i 1 1 − a i x = ∑ i ∏ j ≠ i ( 1 − a j x ) ∏ i ( 1 − a i x ) \sum_i\frac1{1-a_ix}=\frac{\sum_i\prod_{j\ne i}(1-a_jx)}{\prod_i(1-a_ix)} ∑i1−aix1=∏i(1−aix)∑i∏j̸=i(1−ajx) 求出,复杂度 O ( n log 2 n + t log t ) O(n\log^2n+t\log t) O(nlog2n+tlogt)。
在本题的应用中,都有 t = n − 2 t=n-2 t=n−2,复杂度 O ( n log 2 n ) O(n\log^2n) O(nlog2n)
套路一讲到我们要求 ∏ F ( a i x ) \prod F(a_ix) ∏F(aix),其中 F ( x ) = ∑ x k k ! w ( k + 1 ) F(x) = \sum\frac{x^k}{k!} w(k+1) F(x)=∑k!xkw(k+1)
套上ln将积转为和 exp ( ∑ ln F ( a i x ) ) = exp ( ∑ ( ln F ) ( a i x ) ) \exp(\sum\ln F(a_ix)) = \exp(\sum(\ln F)(a_ix)) exp(∑lnF(aix))=exp(∑(lnF)(aix))
因此我们对 F F F 取 ln \ln ln,执行一遍套路二,再 exp \exp exp 回来即可。
现在考虑原题的 v a l ( d ) = ( ∏ i = 1 n d i m ) ( ∑ i = 1 n d i m ) val(d) = (\prod_{i=1}^n d_i^m ) (\sum_{i=1}^n d_i^m) val(d)=(∏i=1ndim)(∑i=1ndim),尝试表示成积的形式,发现它就是硬点了某个 i i i 不贡献 w ( d i ) = d i m w(d_i)=d_i^m w(di)=dim 而贡献 w ′ ( d i ) = d i 2 m w'(d_i)=d_i^{2m} w′(di)=di2m。
相应地再设 F ′ ( x ) = ∑ x k k ! w ′ ( k + 1 ) F'(x) = \sum\frac{x^k}{k!} w'(k+1) F′(x)=∑k!xkw′(k+1),那么就要枚举 i i i 并把一个参与 ∏ \prod ∏ 的 F ( a i x ) F(a_ix) F(aix) 替换成 F ′ ( a i x ) F'(a_ix) F′(aix)。
( ∏ F ( a i x ) ) ( ∑ i = 1 n F ′ ( a i x ) F ( a i x ) ) (\prod F(a_ix))(\sum_{i=1}^n\frac{F'(a_ix)}{F(a_ix)}) (∏F(aix))(i=1∑nF(aix)F′(aix))
求出 G = F ′ F G=\frac{F'}F G=FF′ 再执行一遍套路二即可。
综上,共需求1次等幂和(含1分治FFT、1求逆、1乘法)、1 ln \ln ln、1 exp \exp exp、1求逆、2乘法。复杂度 O ( n log 2 n + n log m ) O(n\log^2n+n\log m) O(nlog2n+nlogm),其中 log m \log m logm 是快速幂。
m m m 可以做1e9。提交记录 3e4 跑了不到 160ms,预计 2.5s 内可以做到 2.6e5 或 5.2e5。
WC2019 T1 数树 也是一道关于“把 m m m 个大小不一的连通块用 m − 1 m-1 m−1 条边连成树”的计数。考场上发现自己完全记不起清华集训的式子了。于是回来整理了一下这题,并总结一下 prufer 序列的性质。
众所周知,prufer 序列是每次删去编号最小的叶子并记录相邻结点编号得到的长 n − 2 n-2 n−2 的序列。
扩展到 N N N 结点已结成 m m m 个连通块的情形,我们记录2个数组:
设第 i i i 个连通块大小为 a i a_i ai,那么显然每个 f i f_i fi 有 N N N 种取值, g i g_i gi 有 a i a_i ai 种取值。
结论一:生成树个数为 N m − 2 ∏ i = 1 m a i N^{m-2}\prod_{i=1}^ma_i Nm−2∏i=1mai
结论二:用 egf 把序列 f f f 的 m − 2 m-2 m−2 个位置分配给 m m m 个块,若第 i i i 块分到 c i c_i ci 个位置,那么其度数为 d i = c i + 1 d_i=c_i+1 di=ci+1,并且这样的方案数为 ( n − 2 ) ! ∏ c i ! ∏ a i c i + 1 \frac{(n-2)!}{\prod c_i!}\prod a_i^{c_i+1} ∏ci!(n−2)!∏aici+1
相比起来,清华集训题需要依据度数计算权值 w ( d i ) w(d_i) w(di),故采取结论二,考虑 f f f 序列的形式。而WC题无需考虑 d i d_i di 的细节,只关心连通块划分情况对方案的影响,故只需用结论一的公式。
我们来表演一下用结论一秒切WC题。(似乎断句有歧义…是“结论一♂秒切”不是一秒切)
令两棵树的贡献为 y 重边数 y^\text{重边数} y重边数
首先显然“硬点重边并确保其它边不重”肯定不如“硬点至少重了哪些边”好算。答案是前者的方案数乘上权值 y ∣ S ∣ y^{|S|} y∣S∣ 求和,那我们一定可以用后者的方案数乘上某权值来求和以求出答案。
稍作思考可发现我们要的权值就是 ( y − 1 ) ∣ T ∣ (y-1)^{|T|} (y−1)∣T∣,这来自非常简单的组合恒等式 ∑ T ∈ S ( y − 1 ) ∣ T ∣ = y ∣ S ∣ \sum_{T\in S}(y-1)^{|T|}=y^{|S|} ∑T∈S(y−1)∣T∣=y∣S∣。你可以用组合意义或二项式定理或任何方式理解它。
现在硬点了一些边,就是把 N N N 个点已连通成若干块。
抬出公式 N m − 2 ∏ a i N^{m-2}\prod a_i Nm−2∏ai,其中 a i a_i ai 是选若干树边后把树割成的连通块大小。带上权值是 ( y − 1 ) m − 1 N m − 2 ∏ a i (y-1)^{m-1}N^{m-2}\prod a_i (y−1)m−1Nm−2∏ai
树上dp, ( y − 1 ) m − 1 N m − 2 (y-1)^{m-1}N^{m-2} (y−1)m−1Nm−2 显然很好 O ( N ) O(N) O(N) 做,只要每划分一个新块就乘 ( y − 1 ) N (y-1)N (y−1)N 即可。
这是0次项之和,现要计算 a i a_i ai 的1次项之和,只要同时记录0,1次项即可。也可以按 laofu 那样用组合意义理解为“每块选一个关键点”。
考虑这个组合结构: N N N 个点拆分为 m m m 个连通块,在块内要形成生成树,这是 a i a i − 2 a_i^{a_i-2} aiai−2;若块间有 t t t 种方式连成树,那么两树有 t 2 t^2 t2 的方案。
套公式得 ( y − 1 ) n − m ( N m − 2 ∏ a i ) 2 ∏ a i a i − 2 = ( y − 1 ) n − m N 2 m − 4 ∏ a i a i (y-1)^{n-m}(N^{m-2}\prod a_i)^2\prod a_i^{a_i-2} = (y-1)^{n-m}N^{2m-4}\prod a_i^{a_i} (y−1)n−m(Nm−2∏ai)2∏aiai−2=(y−1)n−mN2m−4∏aiai
所以一个连通块 a i a_i ai 贡献 ( y − 1 ) − 1 N 2 a i a i (y-1)^{-1}N^2a_i^{a_i} (y−1)−1N2aiai, 对 egf F ( x ) = ∑ x k k ! ( y − 1 ) − 1 N 2 k k F(x) = \sum\frac{x^k}{k!} (y-1)^{-1}N^2k^k F(x)=∑k!xk(y−1)−1N2kk 做 exp \exp exp 即可。