多项式题目总结
最近把学长讲的生成函数, 多项式(也不知道叫啥, 反正要推式子)的题都做了, 趁还记得写个总结.
P2000 拯救世界
普通型生成函数板子题.
定义一个多项式(A(x) = sum_{i=0}^{infty} a_i*x^i)第(i)项的系数(a_i)为石头数量为(i)时的答案.
把它和另外一个多项式((B(x) = sum_{i=0}^{infty} b_i*x^i))乘起来就是 : (C(x) = sum_{i=0}^{infty} sum_{j=0}^{infty} a_i*b_j*x^{i+j}), 会得到石头数量为(i+j)的答案.
比如说第一个, 金神石需要是6的倍数, 那我们就可以拿总数为0, 6, 12, 18, 24...的石头, 对应的多项式就是 : (1 + x^6 + x^{12} + x^{18} + dots)
木神石最多用九块, 那我们就可以拿总数为0, 1, 2, 3, ... , 9的石头, 对应的多项式就是(1 + x + x^2 + dots + x^9).
最后我们把每一个多项式都乘起来, 所得的(x^n)的系数就是总数为(n)块石头时的合法方案数了.
P2012 拯救世界2
指数型生成函数板子题.
定义一个多项式(A(x) = sum_{i=0}^{infty} a_i* frac{x^i}{i!})第(i)项的系数(a_i)是基因序列长度为(i)时的答案.
把它和另外一个多项式((B(x) = sum_{i=0}^{infty} b_i *frac{x^i}{i!}))乘起来就是 : (C(x) = sum_{i=0}^{infty} sum_{j=0}^{infty} a_i* frac{x^i}{i!} b_j* frac{x^j}{j!} = sum_{i=0}^{infty} sum_{j=0}^{infty} frac{a_i *b_j*(i+j)!}{i! * j!}* frac{x^{i+j}}{i+j!} = sum_{i=0}^{infty} sum_{j=0}^{infty} C_{i+j}^{i}a_i *b_j* frac{x^{i+j}}{i+j!}), 会得到基因序列长度为(i+j)的答案.
这道题和上一道题的区别就在于 : 这道题有顺序, 上道题没有. 所以这里要多乘上一个(C_{i+j}^{i}), 表示要从前(i+j)个位置中选出(i)个位置放(a).
首先我们需要知道这四个公式 :
这道题里第一个条件是(ATCG)随便放, 那就是 ((sum_{i = 0}^{infty} frac{x^i}{i!})^4).
第二个条件是只能放奇数次, 那就是 ((sum_{i = 0}^{infty} frac{x^{2i + 1}}{(2i + 1)!})^4)
第三个偶数次同理 ((sum_{i = 0}^{infty} frac{x^{2i}}{(2i)!})^4)
最后答案需要把这三个乘起来, 化简之后就可以得到 : (Large(frac{e^{3x} - e^{-x}}{4})^4)
继续化简(繁) : (frac{1}{256}(e^{12x} - 4e^{8x} + 6e^{4x} + e^{-4x} - 4))
由于我们只需要求第(n)项的系数就好了,根据第一个公式 : (sum_{i = 0}^{infty} c^i * frac{x^i}{i!} = e^{cx}), 式子又可以变成 : (frac{1}{256}(12^n - 4 * 8^n + 6 *4 ^ n + (-4)^n)), 快速幂就好了.
P5396 第二类斯特林数·列
我们需要求出一列的斯特林数, 那我们就设多项式(F_n(x) = sum_{i=0}^{n} S(i, n) * x^i)
根据斯特林数的递推公式(S(n, m) = S(n - 1, m - 1) + S(n - 1, m) * m)我们可以写出 : (F_n(x) = x*F_{n-1}(x) + nxF_{n}(x))
稍微推一推 :
然后分治做就好啦.
P5395 第二类斯特林数·行
(m^n = sum_{i=0}^{m}C_m^i left { egin{array}{l} n\i end{array} ight } i!)
等式右边表示枚举非空集合的个数, 等式左边是球不同, 盒子也不同, 可空的方案数.
然后我们二项式反演一下 : (left { egin{array}{l} n \ m end{array} ight } m! = sum_{i=0}^{m} (-1)^{m-i}*C_{m}^i *i^n)
把组合数展开, 同时消去两边的(m!) : (left { egin{array}{l} n \ m end{array} ight } = sum_{i=0}^{m} frac{(-1)^{m-i}}{(m-i)!}*frac{i^n}{i!})
显然这是一个和卷积(其实还有差卷积, 下面会有)的形式, 直接NTT加速就好了.
P4841 [集训队作业2013]城市规划
简化题面之后, 就是让你求(n)个点的有标号无向连通图个数有多少个(题面里好像有).
设(f_i)是(i)个点的答案, (g_i)是(i)个点的图的数量(连不连通都可).
也就是说(large g_i = 2^{C_i^2}). 一个(i)个点的完全图有(C_i^2)条边, 每条边都可以存在或不存在于当前图中, 于是就有了上式.
考虑单步容斥 :
不连通的图的个数就是, 枚举与1这个点在一个连通块内的点, 剩下的点随便.
移项一下 :
拆开一下组合数 :
这不和卷积?直接NTT加速就完事了.(对于第0项加上它其实对答案没有影响的)
CF438E The Child and Binary Tree
设(f_i)代表权值为(i)的二叉树的个数, (g_i)代表权值(i)是否出现过, 出现过就是1, 没有就是0.
可以得到 :
设多项式(F(x) = sum_{i=0}^{infty} f_i * x^i), (G(x) = sum_{i=0}^{infty} g_i * x^i).
那么又可以得到 :
为啥要+1呢? 因为(f_0=1), 而这两个多项式卷起来使得(f_0=0)了, 就不对了.
解出(F(x))
然后多项式开根, 多项式求逆就好了.
有个问题就是(F(x))可以解出两个解, 但是(F(x) = dfrac{1 + sqrt{1-4G(x)}}{2G(x)})这个解是不收敛的, 所以不取它.(虽然我也不知道为啥, 但是这个用的挺多的, 下面一道题也用到了这个.)不收敛就是说当(x)趋于无穷的时候, 它也趋近无穷, 相反它趋于0的话就叫做收敛.
P3978 [TJOI2015]概率论
还是设(f_i)表示(i)个点的二叉树所有情况的叶子节点总数, (g_i)表示(i)个节点的二叉树的个数.那么最后的答案就是(dfrac{f_n}{g_n})
首先(g_i)很好搞 : (g_n = sum_{i=0}^{n - 1}g_i * g_{n-1-i}, g_0 = 1), 和上一道题差不多.
然后设(G(x) = sum_{i=0}^n g_i * x^i), 那么可以得到 :
解出(G(x)), 同样舍去那个不收敛的解.
(f_i)也是一样的 : (f_n = sum_{i=0}^{n-1} f_i*g_{n-1-i} + f_{n-1-i}*g_{i}, f_0=0, f_1 = 1)
设(F(x) = sum_{i=0}^{infty} f_i * x^i), 可以得到 :
加(x)和上一道题同理.
解出(F(x))
我们又发现有这个东西 :
很神奇对不对? 这样我们就可以找出(g_i)与(f_i)的关系了, 这两个多项式对应项相等, 可以得到 : (f_n = ng_{n-1})
所以 : (Ans = dfrac{f_n}{g_n} = dfrac{ng_{n-1}}{g_n} = dfrac{n(n+1)}{2(2n-1)}), 我们就可以(O(1))算啦!
P4389 付公主的背包
老套路了 : 设(f_i)为恰好装(i)体积的商品的.....才怪啊!并不是每道题都要这么做.
考虑生成函数(F(x) = Pi_{i=1}^{n}sum_{j=1}^{infty} x^{j*v_i}), 最后第(x_i)项的系数就是恰好体积为(i)的方案数.
可是这玩意很不好做, 考虑变换一下形式吧. 首先 (sum_{j=1}^{infty} x^{j*v_i} = dfrac{1}{1-x^{v_i}}), 这东西用推等比数列求和公式的方法推就好了.
一遍连乘是不好操作的, 但是连乘就是连加, 两遍取个对数就好了, 于是上式就变成了 :
(sum)后边那个东西不好求, 给它变换一下形式, 思路就是先求导, 在积分回去 :
(ln(dfrac{1}{1-x^{v_i}}))
(= int (1-x^{v_i})(sum_{j=0}^{infty}jv_i*x^{jv_i-1}) dx) (注意复合函数的求导法则)
(=int (sum_{j=0}^{infty}jv_i*x^{jv_i-1})-(sum_{j=0}^{infty}jv_i*x^{(j+1)v_i-1}) dx)
(=int (sum_{j=0}^{infty}jv_i*x^{jv_i-1})-(sum_{j=1}^{infty}(j-1)v_i*x^{jv_i-1}) dx)
(=int (sum_{j=1}^{infty}v_i*x^{jv_i-1}) dx)
(= sum_{j=1}^{infty} dfrac{x^{jv_i}}{j})
这个形式就很优美了, 所以得到 :
(k_i)表示体积为(i)的商品的数量. 上式直接暴力搞, 复杂度是优美的调和级数.最后直接上多项式exp就可.
P4491 [HAOI2018]染色
这回是真的老套路 :
(large f_i = C_m^i * C_{n}^{is} * frac{(is)!}{(s!)^i} * (m-i)^{n-is})
(f_i)称不上是什么的方案数, 因为有很多重复的, 它的含义是 : 任选(i)个颜色填到(is)个位置上, 并且有顺序, 所以乘上一个多重集合的组合数, 剩下(n-is)个位置随便填(m-i)中颜色.
设(g_i)表示出现次数为(s)的颜色数恰好有(i)个的方案数.
设(up = min(m, n/s))
可以得到 : (f_i = sum_{j=i}^{up} C_j^i * g_j)
举个例子 : 在(f)中, {a,b,c,d}这个集合在枚举{a,b,c},{a,b,d},{a,c,d},{b,c,d}的时候都被算了一次.
对上式在二项式反演一下 : (g_i = sum_{j=i}^{up}(-1)^{j-i}*C_j^i*f_j) (注意这个和上面有个题的二项式反演不太一样)
还是把组合数拆开 :
这就转化成了差卷积的形式.但是差卷积具体怎么算呢? 这个东西想了好久, 网上也没有搜到.
设(A_i = frac{(-1)^{i}}{i!}), (B_i = f_i * i!), 可以得到 :
具体算法就是先把(B)数组反转, 然后再像和卷积那么做, (A_{j-i} * B_{n-j}), 就得到翻转过后的答案(Ans_{n-i}).
P5824 十二重计数法
这题有点ex吔
1.球之间互不相同,盒子之间互不相同:
每个球都有(m)个位置可以放, 就是(m^n).
2.球之间互不相同,盒子之间互不相同,每个盒子至多装一个球:
首先(n <= m), 第一个球有(m)个盒子可以放, 第二个有(m-1)个盒子可以放, 以此类推, 第(n)个球有(m-n+1)个盒子可以放, 也就是(m(m-1)(m-2)dots(m-n+1))
3.球之间互不相同,盒子之间互不相同,每个盒子至少装一个球 :
首先(n>=m), 然后我们可以枚举空的盒子数(i), 那么(C_m^i * (m-i)^n)就是空(i)个盒子的方案数, 然后稍微容斥一下就可以了 : (sum_{i=0}^m = (-1)^i * C_m^i * (m-i)^n)
4.球之间互不相同,盒子全部相同 :
解决4之前先把6解决了吧.
6.球之间互不相同,盒子全部相同,每个盒子至少装一个球 :
6就是我们说的第二类斯特林数, 上面已经有了第二类斯特林数行和列的求法了, 这里就不再说了.
那么4的话就是(sum_{i=0}^{m} S(n,i)), 因为有盒子可以空嘛, 那我们就枚举不空的盒子数量就好了.
5.球之间互不相同,盒子全部相同,每个盒子至多装一个球 :
没什么好说的, 就是 : ([n leq m])
7.球全部相同,盒子之间互不相同 :
解决7之前先解决9吧.
9.球全部相同,盒子之间互不相同,每个盒子至少装一个球 :
可以理解为把(n)个球分成(m)份, 可以用隔板法, 也就是在(n-1)个空隙里插入(m-1)个板子使集合分成(m)份, 那么答案就是 : (C_{n-1}^{m-1}).
那么7和9的区别就是盒子可空, 还是用隔板法, 但是是把问题转换成了不可空, 如果说我们先往(m)个盒子里面都放了一个球, 那么那(n)个球怎么放都不会使盒子为空了, 也就是我们现在有了(n+m)个球, 那么方案数就是 : (C_{n+m-1}^{m-1})
8.球全部相同,盒子之间互不相同,每个盒子至多装一个球 :
直接找有(n)个盒子装球的方案数就好了 : (C_m^n)
10.球全部相同,盒子全部相同 :
这个就不太好做了.
我们设(p(n,m))表示(n)个球相同, (m)个盒子相同, 没有放置限制的方案数是多少.可以得到DP转移方程 :
(p(n,m) = p(n-m,m) + p(n,m-1))
为了使方案不重复, 我们假定每个盒子里放的球数是单调递增的, 那么就可以往(m)个盒子里都加一个球, 也可以加一个空的盒子, 这两种都不会改变原来单增的局面.
设(F_m(x) = sum_{i=0}^{m} p(i,m) x^i), 可以得到 :
这样就转化成付公主的背包那个题了.
11.球全部相同,盒子全部相同,每个盒子至多装一个球 :
直接判断([n <= m])就好了.
12.球全部相同,盒子全部相同,每个盒子至少装一个球 :
类似于7, 把至少装一个球转化成可空, 我们把每个盒子里先垫上一个球, 那么所有盒子肯定都合法了, 所以剩下的(n-m)个球按照10的做法就好了, 也就是(p(n-m,m)).