有一类多项式题,十分考验选手的推式子能力,真正的代码部分仅仅只是几个模板拼凑在一起。这类题目如果出现,往往会造成比较大的分差,所以在此略微归纳一下这类题目的做法。大致如下:
两个主要思想:在解多项式方程的时候,把多项式当做数看,在允许的情况下,可以等式两边同时加减乘除一个多项式;部分题目的多项式可能是无穷项的,在这种情况下,可能会出现把原多项式经过一些操作之后得到自身。
两个主要套路:一个是先想出一个 DP 的做法,然后根据 DP 转移的特性,发现其卷积的性质并把卷积部分弄成多项式,之后直接卷积加速,或者通过解方程的方式求答案;另一个是直接设求解的东西为一个多项式,然后根据其性质使其可以从自己转移到自己,然后解方程。
具体如何使用请看下面两个题目的题解。
[集训队作业2013]城市规划 题解
题意简述:求 \(n\) 个点无重边无自环有标号无向连通图数目。\(n\leq 10^5\)。
题解:我们设 \(f(i)\) 表示 \(i\) 个节点的答案,直接求并不好求,但是我们可以很容易的得到 \(n\) 个点的图的数量,即 \(2^{C_n^2}\) ,考虑怎么用 \(f\) 来表示它。
\(1\) 号节点最终一定会有一个连通块,考虑枚举这个连通块的大小,于是就有 \(2^{C_n^2}=\sum_{i=1}^nC_{n-1}^{i-1}f(i)2^{C_{n-i}^2}\)。也就是 \(i\) 个点形成一个连通块,剩下的点随意连边。
为了方便,设 \(g(i)=2^{C_i^2}\),原式子就变成了 \(g(n)=\sum_{i=1}^nC_{n-1}^{i-1}f(i)g(n-i)\)。
把组合数拆开,移项得 \(\frac{g(n)}{(n-1)!}=\sum_{i=1}^n\frac{f(i)}{(i-1)!}\frac{g(n-i)}{(n-i)!}\),设 \(F(i)=\frac{f(i)}{(i-1)!}\),\(G(i)=\frac{g(i)}{i!}\),后面的求和就是一个卷积的形式,即 \(F\times G\)。
把等式左边也稍加整理一下,就有 \(nG(n)=(F\times G)(n)\)。
我们定义多项式的点乘为对应项相乘,再设 \(H(i)=i\),那么就有 \((H\cdot G)(n)=(F\times G)(n)\),即 \(H\cdot G=F\times G\)。
又因为 \(G\) 的常数项为 \(1\),故 \(G\) 存在逆元,所以可以两边同时卷上 \(G^{-1}\)。于是就有 \(F=(H\cdot G)\times G^{-1}\),写个多项式求逆就可以得到 \(F\) 了。时间复杂度 \(O(n\log n)\)。
CF438E The Child and Binary Tree 题解
题意简述: 有无数个点,每个点的权值可以是给出集合 \(S\) 中的任意一个,定义一棵树的权值是所有点的权值和,求有多少棵节点数目任意的、形态不同的、权值为 \(val\) 的二叉树。对于每个 \(val\leq k\) 都需要求解。\(k,|S|\leq 10^5\)。
题解:直接设多项式 \(f\) 为答案多项式,其中 \(f(i)\) 表示 \(val=i\) 的方案数。特别的,\(f(0)=1\)。现在考虑 \(f\) 怎么求。
设 \(g(i)\) 表示一个点的权值为 \(i\) 的方案数,显然 \(i\in S\) 则 \(g(i)=1\),反之 \(g(i)=0\)。
那么对于当前的,它左儿子的方案数是 \(f\),右儿子的方案数是 \(f\),它自己的方案数是 \(g\),而这个问题把解集合并就相当于是一个背包,那么就有 \(f=f\times f\times g+1\),这个加一是指当前这个点的子树为空。
之后把 \(f\) 当做未知数解方程,根据求根公式,有 \(f=\frac{1\pm\sqrt{1-4g}}{2g}\),现在需要考虑正负取正还是负。
我们可以这么分析,当 \(g\) 趋近于 \(0\) 也就是 \(|S|\) 趋近于 \(0\) 的时候,\(f=\frac{1\pm1}{0}\),而此时方案数是为 \(0\) 的,也就是 \(f\) 为 \(0\),那么就只能取负号,所以 \(f=\frac{1-\sqrt{1-4g}}{2g}\)。
\(g\) 常数项不是 \(1\),没有逆元,考虑把分子有理化。就有 \(f=\frac{2}{1+\sqrt{1-4g}}\)。多项式开根加个求逆即可。复杂度 \(O(n\log n)\)。
上述题目,第一题用的是第一个 trick,第二题用的是第二个 trick,较好的体现了做多项式题目的技巧。且这两个题目十分经典,不失为练习多项式的好题。