官方题解只能做到 $O(n^3)$?玩的太差了。这题可以降到 $O(N^2\log^2 N+(\log M)^3)$ 时间、$O(N+\log^2 M)$ 额外空间。下面的实现支持任意合法模数,不要求模数为质数。已有的三次 DP 可以作为对拍基准。([Cnblogs][1])
题目要求同时输出所有 $2\le n\le N$ 的答案,其中 $N\le500$,$10\le M\le2^{30}$,模数可能是偶数或合数。这里最需要小心的地方,正是不能随意使用阶乘逆元或除以某个特征值之差。
从容斥到可分离的微分算子
记答案为 $a_n$。首先将两棵树的生成方向统一。
对于一棵父亲编号小于儿子编号的树,从排列 $[1]$ 开始,按照编号递增的顺序,将每个点插入其父亲的紧后方。这是一个双射:反过来不断删除当前最大的编号,删除前它的前驱就是父亲。
在最终排列中,一个点非叶,当且仅当它的后继比它大。因为插入该点时,它后面的点一定比它小;只有以后往它后面插入儿子,才会让它的后继变大。将排列首尾相接后,这个结论仍然成立,因为最后一个点到 $1$ 的边不可能上升。
对于父亲编号大于儿子编号的树,完全类似地从 $[n]$ 开始,按照编号递减的顺序插入。此时,一个点非叶,当且仅当环上后继比它小。
因此,将第二棵树对应的环旋转到以 $1$ 开头,再通过上述双射还原成递增树,就会将每个点的叶子、非叶子状态互换。原题于是等价于:统计两棵递增树,使它们的非叶子集合相同。
设 $f(S)$ 表示非叶子集合恰为 $S$ 的递增树数量,$g(A)$ 表示只允许 $A$ 中的点作为父亲的数量,其中 $S,A\subseteq[n-1]$。显然有 $g(A)=\prod_{i=2}^n|A\cap[i-1]|$,而答案为 $\sum_S f(S)^2$。
由子集容斥,$f(S)=\sum_{A\subseteq S}(-1)^{|S|-|A|}g(A)$。展开平方并先枚举 $A,B$,得到
$$ a_n=\sum_{A,B\subseteq[n-1]} (-1)^{|A\triangle B|} 2^{n-1-|A\cup B|}\,g(A)g(B). $$
对于每个点,不属于两集合、只属于 $A$、只属于 $B$、同时属于两集合,权值分别为 $2,-1,-1,1$。用 $x,y$ 的指数记录已经出现的两类可选父亲数量,那么加入一个点对应乘上 $P(x,y)=2-x-y+xy$。
随后,为下一个点选择两棵树中的父亲。若当前指数为 $(j,k)$,应乘上 $jk$,这正好可以用微分算子 $D_x=x\partial_x$、$D_y=y\partial_y$ 表示。因此定义 $F_0=1$、$F_{r+1}=D_xD_y(PF_r)$,便有 $a_n=F_{n-1}(1,1)$。
直接维护 $F_r$ 的二维系数仍然是三次复杂度。真正的优化在下面这个变量替换。
先假设模数为奇数,令 $x=2/(1+t)$、$y=2/(1+u)$,并定义 $F_r(x,y)=(1+t)(1+u)H_r(t,u)$。代入后得到 $H_0=1/((1+t)(1+u))$,以及 $H_{r+1}=\mathcal K H_r$,其中 $\mathcal K h=2\partial_t\partial_u((1+tu)h)$。
原来的求值点 $x=y=1$ 对应 $t=u=1$,所以 $a_n=4(\mathcal K^{n-1}H_0)(1,1)$。
现在观察 $\mathcal K$ 对单项式的作用:
$$ \mathcal K(t^a u^b) = 2(a+1)(b+1)t^a u^b + 2ab\,t^{a-1}u^{b-1}. $$
两个指数之差 $a-b$ 完全不变。 原来的二维系统被拆成了若干互不相关的双对角系统。
还需要将有理函数 $H_0$ 换成有限多项式。取 $1/(1+t)$ 在 $t=1$ 处的前 $N$ 项,即 $r(t)=\sum_{k=0}^{N-1}(-1)^k(t-1)^k/2^{k+1}$。
由于 $\mathcal K^{n-1}$ 对每个变量最多求导 $n-1$ 次,对于所有 $n\le N$,将 $H_0$ 替换成 $r(t)r(u)$ 都不会改变最终在 $(1,1)$ 的求值结果。
设 $r(t)=\sum_{j=0}^{N-1}r_jt^j$。由 $(1+t)r(t)=1-((1-t)/2)^N$,可以得到 $r_j=(-1)^j\left(1-2^{-N}\sum_{k=0}^j\binom Nk\right)$。用 Pascal 递推计算第 $N$ 行组合数,总共只需 $O(N^2)$ 时间,不需要任何阶乘逆元。
近二次计算与任意模数
固定指数差 $d\ge0$,令 $L=N-d$,取基底 $e_j=t^{j+d}u^j$,其中 $0\le j< L$。这一条对角线上的初始系数为 $v_j=r_{j+d}r_j$。
记 $\lambda_j=2(j+1)(j+d+1)$,那么 $\mathcal K e_j=\lambda_j e_j+\lambda_{j-1}e_{j-1}$,其中 $j=0$ 时忽略第二项。
为了同时得到所有迭代次数的结果,引入普通生成函数。设 $(I-z\mathcal K)^{-1}\sum_jv_je_j=\sum_jy_j(z)e_j$,则
$$ y_j(z)=\frac{v_j+z\lambda_jy_{j+1}(z)}{1-z\lambda_j}, \qquad y_L(z)=0. $$
所有基底在 $(1,1)$ 处的值都为 $1$,因此这一条对角线的贡献是 $R_d(z)=\sum_{j=0}^{L-1}y_j(z)$。利用 $t,u$ 的对称性,令 $G(z)=4R_0(z)+8\sum_{d=1}^{N-1}R_d(z)$,最终输出 $[z^{n-1}]G(z)$ 即可。所有计算都只需要保留模 $z^N$ 的结果。
不能逐项展开上述递推,否则每条对角线仍要计算 $N$ 层。我们改用多项式分治,直接构造 $R_d$ 的分子、分母。
对于区间 $[l,r)$,维护五个多项式 $Q,A,B,C,D$,满足 $y_l=(Ay_r+B)/Q$,以及 $\sum_{j=l}^{r-1}y_j=(Cy_r+D)/Q$。
单点 $j$ 的信息为 $Q=1-\lambda_jz$、$A=C=\lambda_jz$、$B=D=v_j$。将相邻的左右两段合并,用下标 $1,2$ 表示它们的信息,则:
$Q=Q_1Q_2$,$A=A_1A_2$,$B=B_1Q_2+A_1B_2$。
$C=C_1A_2+C_2Q_1$,$D=D_1Q_2+C_1B_2+D_2Q_1$。
这些公式只是将右段的 $y_{\mathrm{mid}}$ 代入左段。注意,长度为 $\ell$ 的区间中,$A$ 始终是形如 $az^\ell$ 的单项式,所以与 $A$ 相乘只需平移和数乘,不必做卷积。
整条对角线的右边界为 $y_L=0$,因此分治完成后直接得到 $R_d=D/Q$。
若多项式乘法的复杂度为 $O(\ell\log\ell)$,则处理长度 $L$ 的对角线需要 $O(L\log^2L)$ 时间。所有对角线长度为 $N,N-1,\ldots,1$,总时间为 $O(N^2\log^2N)$。
各条对角线的分式可以计算完后立即加入总分式。两个分式按 $(p_1q_2+p_2q_1)/(q_1q_2)$ 合并,并始终截断到 $z^N$,这部分总共只需 $O(N^2\log N)$ 时间。最后对总分母求一次逆,再乘上总分子即可。所有分母的常数项都为 $1$,所以即使奇数模数是合数,这些操作仍然合法;完全不需要特征值互异,也不需要除以 $\lambda_i-\lambda_j$。
实现中,任意模数卷积使用三个 NTT 素数 $998244353$、$1004535809$、$469762049$。输入系数都先规范到 $[0,M)$,一个整数卷积系数小于 $N(M-1)^2< 2^{69}$,而三个素数的乘积大于 $2^{88}$,因此可以先精确 CRT 重建整数卷积,再对目标模数取模。这里不要求目标模数与这些 NTT 素数互质。
接下来处理偶数模数。写成 $M=2^e m$,其中 $m$ 为奇数,上述算法负责模 $m$ 的部分。对于模 $2^e$,有一个很有用的整除性质。
对原题使用另一种容斥:将所有点划分为 $A,B,C$,分别表示允许作为第一棵树的父亲、允许作为第二棵树的父亲、两者都不允许,三类点的权值分别为 $1,1,-2$。设对应的树数量为 $g_1(A),g_2(B)$,则 $a_n=\sum_{A\sqcup B\sqcup C=[n]}(-2)^{|C|}g_1(A)g_2(B)$。
这个容斥可以逐点检查:若一个点在两棵树中均非叶,则没有合法分类;若在两棵树中均为叶,则三种分类的权值和为 $1+1-2=0$;若恰在一棵树中非叶,则只能分到对应一类,贡献 $1$。
设一个非零项中三类点数为 $a,b,c$。必有 $1\in A$、$n\in B$。在 $g_1(A)$ 中,按编号排列的 $A$ 中非根节点提供因子 $1,2,\ldots,a-1$,点 $n$ 提供因子 $a$,所以 $a!\mid g_1(A)$。对第二棵树同理有 $b!\mid g_2(B)$。因此每一项都满足
$$ v_2\!\left(2^c g_1(A)g_2(B)\right) \ge c+\left\lfloor\frac a2\right\rfloor+ \left\lfloor\frac b2\right\rfloor \ge \left\lfloor\frac{n-1}{2}\right\rfloor. $$
于是 $n\ge2e+1$ 时,答案模 $2^e$ 恒为零。只需用普通三次 DP 计算前 $K=\min(N,2e)$ 项;题目中 $e\le30$,所以最多处理 $60$ 个点。
这个小 DP 在处理编号 $i$ 前,记录左侧有 $j$ 个 $A$ 类点、右侧含当前点有 $k$ 个 $B$ 类点。将当前点分入 $A,B,C$,分别产生转移 $(j,k)\to(j+1,k)$、$(j,k)\to(j,k-1)$、$(j,k)\to(j,k)$,权值分别为 $jk$、$j(k-1)$、$-2jk$。初始化 $f[1][k]=k$;最后一个点强制属于 $B$,答案为 $\sum_jj f[j][1]$。
最后对模 $2^e$ 和模 $m$ 的答案做一次 CRT。额外的小 DP 需要 $O(e^3)$ 时间、$O(e^2)$ 空间;多项式分式计算完后立即合并,不保存所有对角线,所以主算法额外空间为 $O(N)$。
综上,得到 $O(N^2\log^2N+(\log M)^3)$ 时间、$O(N+\log^2M)$ 额外空间。这是一个可证明的近二次上界;这里没有给出匹配下界,因此不将其声称为已经证明不可继续改进的复杂度。