一些生成函数题目
是阅读 zscoder 两篇博客的整理笔记。
[Tutorial] Generating Functions in Competitive Programming (Part 1)
[Tutorial] Generating Functions in Competitive Programming (Part 2)
给定 \(n,k\),求有多少个长度为 \(n\) 的排列 \(p\),满足对于 \(k|i\) 且 \(i<n\) 的下标,\(a_{i}>a_{i+1}\),而剩下的地方 \(a_i<a_{i+1}\) 。\(2\leq k< n\leq 5\times 10^5\)
限制相当于有若干个分界线,界线之间的段满足单增,而段间满足界线左侧小于右侧。记 \(S=\{a_1,a_2,...,a_m\},a_1<a_2<...<a_m\) 为分界线的集合, 记 \(f(S)\) 为此限制下的排列数量。
考虑容斥,记 \(g(S)\) 为满足的限制为 \(S\) 的子集的排列数量,即 \(g(S)=\sum_{T\sube S}f(S)\),则有:
于是转向计算 \(g(S)\),设 \(b_0,b_1,..,b_m\) 为 \(S\) 分出来的段的长度,\(b_i=a_{i+1}-a_i,a_0=0,a_{m+1}=n\),由于只需要保证段内部单增就行了,所以
而 \(S=\{k,2k,3k,...\}\),所以 \(b\) 满足 \(k|b_0,..b_{m-1}\;,\;k|(n-b_m)\),于是带回 \(f(S)\) 中:
注意到对 \(k\) 同余的 \(n\) 有较大的共同点,记 \(n\equiv r\!\!\!\mod k\),\(S\) 是 \(n\) 决定的,这里用 \(f(n)\) 指代 \(f(S)\),设 \(F(x)\) 是 \(f(qk+r)\) 的 \(EGF\) :
多项式求逆即可。
\(n\) 个开关,初始有开有关,用 \(s_i\) 表示第 \(i\) 个开关的初始状态,每次随机选择一个开关翻转它的状态,第 \(i\) 个开关被选择的概率为 \(\frac{p_i}{S}\),其中 \(S=\sum p_i\) 。求所有开关被关上所需的期望轮数。
\(n\leq 100,S\leq 50000\)
记 \(a_i\) 为 \(i\) 步后所有开关处于关上状态的概率,\(b_i\) 为 \(\forall j,s_j=0\) 时 \(i\) 步后全关的概率,\(c_i\) 为游戏在 \(i\) 步结束的概率(即第一次全关),可以发现有:
令 \(A(x),B(x),C(x)\) 为三者的 \(OGF\),则 \(C(x)=\frac{A(x)}{B(x)}\),由 \(c_i\) 可以直接得到答案,考虑计算 \(A(x),B(x)\) 。
先从 \(B(x)\) 入手,记 \(f_i\) 为第 \(i\) 个开关被翻转的次数,那么一种状态 \((f_1,f_2,...,f_n)\) 被达到的概率为:
对于 \(b_k\) 来说,\(f_i\) 皆为偶数,设 \(B_e(x)\) 为 \(b_i\) 的 \(EGF\),那么有
注意到
类似地可以得到
而对于 \(A_e(x)\),\(s_i=1\) 的部分,便是要求上式中 \(j\) 为奇数,是 \(\frac{1}{2}(e^x-e^{-x})\) 的形式,所以
为了得到 \(A(x)\),我们将上式中的括号暴力展开,可以发现展开后的项都是 \(g_i \exp(\frac{i}{S}x),i\in[-S,S]\) 的形式,共 \(2S\) 项,设 \(dp_{i,j}\) 表示展开前 \(i\) 项后 \(\exp(\frac{j}{S}x)\) 的系数 \(g_j\),\(O(nS)\) 做一遍 DP 就可以得到展开式。此时
对于 \(A(x)\),将 \(n!\) 去掉即可
\(B(x)\) 可以通过完全相同的方式得到。
现在考虑计算答案,期望轮数是
但是注意到在上面和式中,\(\frac{1}{1-\frac{i}{S}x}\) 在 \(i=S,x=1\) 时是未定义的,所以事先乘上 \((1-x)\),将这项抵消,那么记 \(F(x)=(1-x)A(x),\;G(x)=(1-x)B(x)\),答案同样为
于是将 \(F(1),F'(1),G(1),G'(1)\) 的值 \(O(S)\) 算出,带到原式中即得答案。
求 \(\displaystyle\sum_{i\equiv r(\!\!\!\mod m)}\binom{n}{i}\) 对 \(MOD\) 取模的结果。
\(1\leq n\leq 10^{18},2\leq m\leq 2000,0\leq r\leq m-1,10^8\leq MOD\leq 10^9\)
单位根反演:记 \(\omega\) 为 \(m\) 的一个单位根,使得 \(m\) 是最小的满足 \(\omega^m=1\) 的正整数,那么有
由等比数列求和公式易证。
那么在这里,考虑
我们将 \((1+1)^n,(1+\omega)^n,(1+\omega^2)^n,...,(1+w^{m-1})^n\) 求和到一起,而使 \(\binom{n}{qm+r}\) 形式的项前面的系数是 \(\omega^0,\omega^m,\omega^{2m}\) 的样子:
对于计算上式,设 \(F(x)\equiv x^{m-r}(1+x)^n\mod (x^m-1)\),其系数为 \(F(x)=\sum_{i=0}^{m-1}{a_i x^i}\),则所求答案为
所以 \(F(x)\) 的常数项即为答案。
对于所有满足 \(\sum_{i=1}^kx_i=n,\;\forall i,d|x_i\) 的 \((x_1,x_2,...,x_k)\),求出 \(\displaystyle\frac{n!}{x_1!x_2!...x_k!}\) 。
\(n\leq 10^9,k\leq 2000,d\in\{4,6\}\),答案对 \(19491001\) 取模。
要求的即
考虑单位根反演,记 \(P(x)=\sum_{n\geq 0}\frac{x^n}{n!}=e^x\)
\(d\) 是最小的满足 \(\omega^d=1\) 的正整数,这里的 \(d\) 个单位根为
- \(d=4\) : \(1,-1,\omega,-\omega\)
- \(d=6\) : \(1,-1,\omega,-\omega,1-\omega,\omega-1\)
所以 \(e^{x\omega^i}\) 可以表示为 \(e^{(a_i+b_i\omega)x}\) 的形式,将其拆分为 \(e^{a_ix}\) 和 \(e^{b_i\omega x}\) 相对独立的两部分,记 \(u=e^x,v=e^{\omega x}\),所求即为
由于 \(-1\leq a_i,b_i\leq 1\),所以展开式子后至多有 \((2k+1)^2\) 项,是可以接受的。
负指数不好处理,于是平移 \(u^kv^k\),记 \(F(u,v)=\displaystyle \sum_{i=0}^{d-1}u^{a_i+1}v^{b_i+1}\),\(G(u,v)=F(u,v)^k=\displaystyle\sum_{0\leq i,j\leq 2k}g_{i,j}u^iv^j\),此时做一遍二维 \(FFT\) 似乎就可以解决问题了,但是观察一下 二维 FFT 模板题,\(1e3\) 的范围开了 \(2s\),此题 \(2e3\) 开了 \(1s\),看起来时限不太可过,于是继续观察性质。
对 \(u\) 求偏导
比较式子两侧 \(u^iv^j\) 的系数
下标的选取是考虑到 \(f_{0,0}=0,f_{0,1}\neq 0\),注意到右式中的 \(g_{x,y}\) 满足 \(x\leq i\) 或 \(x=i,\;y\leq j-1\),所以我们可以以 \(i\) 从小到大,然后 \(j\) 从小到大的顺序推出所有 \(g_{i,j}\) 。由于 \(f_{i',j'}\) 在 \(i',j'\in[0,2]\) 时才有非零项,所以枚举 \(O(1)\) 个 \((i',j')\) 便可以转移,边界情况是个组合数。
回到计算答案
一种方法是类似上一题的做法,将 \(\omega\) 视为变量
直接对 \(n\) 快速幂求出 \(H(x)\),是 \(O(k^2d^2\log n)\) 的,然后计算 \(H(\omega)\),这可以将 \(\omega^i\) 再次表示为 \(a_i+b_i\omega\) 的形式,最终 \(H(\omega)=k\omega+b\),先前的推导保证了 \(k=1\),所以常数项 \(b\) 即为答案。
不过这前面部分二维 \(FFT\) 的理论复杂度 \(O(k^2\log k)\) 还慢的多,是不可过的。
事实上,\(19491001-1=2^3\times 3\times 5^3\times 73\times 89\),是 \(4\) 和 \(6\) 的倍数,可以算出 \(7\) 是 \(19491001\) 的原根,从而类似 \(NTT\) 的思路,取 \(\omega=7^{\frac{mod-1}{d}}\) 在计算上是等价的,所以我们直接在实数域上计算原式中的每一项即可。
时间复杂度 \(O(k^2\log n)\)
求长度为 \(n\),逆元数为 \(k\) 的排列数量。
\(1\leq n\leq 10^9,0\leq k\leq 10^5,n\geq k\),一个测试点至多 \(100\) 组数据。
Hackerearth - Perfect Permutations
考虑从大到小往排列中添加元素,可以发现对于新添加的元素,其产生的逆序对数与插入的位置一一对应,所以每个元素对逆序对的贡献 \((a_1,a_2,...,a_n)\) 是和排列 \(p_1,p_2,...,p_n\) 一一对应的,所以在 \(n\) 固定时,对 \(k\) 的生成函数即为
\((1-x)^{-n}=\displaystyle\sum_{i\geq 0}\binom{n+i-1}{i}x^i\) 是好处理的,考虑如何计算 \(\displaystyle\prod_{i=1}^n(1-x^i)\) 。
\(\displaystyle\prod_{i=1}^n(1-x^i)\) 朴素的算法是用分治 \(FFT\) 做到 \(O(k\log^2k)\),然而此题数据有 \(100\) 组,显然无法通过。
注意到 \(n\geq k\),次数 \(>k\) 的因式是贡献不到 \([x^k]\) 中的,于是所求等价于 \(\displaystyle\prod_{i=1}^k(1-x^i)\),这就摆脱了 \(n\) 的限制。既然答案与 \(n\) 无关,那就进一步一般化,将式子改为 \(\displaystyle\prod_{i=1}^\infty(1-x^i)\) 也是不影响的。
根据五边形数定理 (Pentagonal number theorem)
我们容易在 \(O(\sqrt k)\) 时间复杂度内得到 \(\displaystyle\prod_{i=1}^\infty(1-x^i)\) 的每一项。
回到计算答案,由于 \(n\) 是 \(10^9\) 级别的,所以组合数只能朴素计算,在枚举 \(i\) 时乘上对应的系数,从而总复杂度仍然是 \(O(k)\) 的。
\(d_{1,1}=d_{1,2}=1\),\(d_{1,i}=d_{1,i-1}+d_{1,i-2}\;(i\geq 3)\),\(d_{i,j}=\displaystyle\sum_{k\leq j}d_{i-1,k}\;(i\geq 2)\),求 \(d_{n,m}\) 。
\(n\leq 2\times 10^5\), \(m\leq 10^{18}\)
square869120Contest #3 G - Sum of Fibonacci Sequence
显然 \(d_{1,k}\) 即斐波那契数列,\(OGF\) 为 \(\frac{x}{1-x-x^2}\)。我们知道,\(OGF\) 中做前缀和是乘上 \(\frac{1}{1-x}\),做差分是乘上 \((1-x)\),所以 \(d_{n,k}\) 的生成函数即为
\([x^m]\frac{x}{1-x-x^2}\) 和 \([x^m](1-x)^{1-n}\) 可以分别在 \(O(\log m)\) 和 \(O(n)\) 内快速得到,但是两者的乘积却很麻烦,根据部分分式分解
Partial fraction decomposition
\(G(x)=\prod_{i=1}^m P_i(x)^{n_i}\),其中 \(P_i(x)\) 为不可约多项式,存在唯一分解:
\[\frac{F(x)}{G(x)}=E(x)+\sum_{i=1}^m\sum_{j=1}^{n_i}\frac{Q_{i,j}(x)}{P_i(x)^j} \]\(\deg Q_{i,j}(x)<\deg P_i(x)\),当 \(\deg F<\deg G\) 时,\(E(x)=0\) 。
在这里有
其中 \(\deg A<n-1,\;\deg B<2\),通分之后与原式比较
由于此式对任意 \(x\) 都成立,而 \(B(x)\) 是 \(kx+b\) 的形式,于是令 \((1-x-x^2)=0\),带入 \(x=\frac{-1\pm\sqrt 5}{2}\):
将数字都表示成 \(a+b\sqrt 5\) 的形式,\((1-\frac{-1\pm \sqrt 5}{2})^{n-1}\) 直接快速幂,容易求出 \(B(x)\) ,此时
因为已知 \(A(x)\) 至多 \(n-2\) 项,所以不用多项式求逆,直接大除法即可。
回到原式,现在所求即为
容易 \(O(n\log mod+\log m)\) 得到上式结果,总时间复杂度也是 \(O(n\log mod+\log m)\) 的。
有一个变量 \(X\) 初始为 \(0\),每一轮以 \(\frac{A_i}{S}\) 的概率选取 \(i\),将 \(X\) 变为 \(X+i\!\!\mod M\),其中 \(1\leq i\leq n,S=\sum_{i=1}^nA_i\) 。求 \(X\) 的值变为 \(K\) 的期望轮数。
\(n\leq \min(500,M-1),2\leq M\leq 10^{18},A_i\leq 100\)
[2019-2020 XX Opencup GP of Tokyo C. Sum Modulo
设 \(E(i)\) 为 \(X\) 变为 \(i\) 的期望步数,设 \(p_i=\frac{A_i}{S}\),则
其中 \(E(-i)=E(M-i)\),可以发现,最终 \(E(n+1),E(n+2),...,E(M-1)\) 都可以表示为 \(c_1E(1)+c_2E(2)+...+c_{n-1}E(n-1)+C\) 的形式(\(E(0)=0\)),那么我们将 \(E(1),..,E(n-1)\) 的表达式都列出来,就会得到 \(n-1\) 个 \(n-1\) 元非平凡线性方程,于是高斯消元便可 \(O(n^3)\) 得到 \(E(1),...,E(n-1)\),进而求出所有 \(E(i)\) 。
对于多项式 \(f(x)=\sum_{i=0}^k a_ix^i\),记 \(val(f)=\sum_{i=0}^k a_iE(i)\),根据递推式,\(i\geq n\) 时
设 \(P(x)=x^n-p_1x^{n-1}-...-p_nx^0\),则 \(val(x^iP(x))=1\),进而 \(val(Q(x)P(x))=Q(1)\) 。
现在我们要求的是 \(E(m)=val(x^m)\),有带余除法 \(x^m=Q(x)P(x)+R(x)\),\(val(x^m)=val(Q(x)P(x)+R(x))=Q(1)+val(R(x))\),考虑分治的思路求出 \(Q(1),R(x)\) 。
\(m\) 为偶时,若 \(x^{m/2}=Q(x)P(x)+R(x)\)
设 \(R(x)^2=Q_2(x)P(x)+R_2(x)\),则 \(x^m\) 对应的两个事物为 \(Q(1)^2P(1)+2Q(1)R(1)+Q_2(1)\) 和 \(R_2(x)\),每一层做一遍带余除法即可,\(m\) 为奇数时给该式多乘个 \(x\) 是容易的,所以是 \(O(n^2\log m)\) 的。
我们需要的是 \(E(M-n+1),...,E(M-2),E(M-1)\),在我们求出 \(val(x^m)=Q(1)+val(R(x))\) 后,显然 \(x^{m+1}\) 就是右式再乘上个 \(x\),对 \(xR(x)\) 再来一次带余除法即可,而 \(x(Q(1))=Q(1)\) ,从而容易在 \(O(n^2)\) 内推出 \(x^{m+1}\),虽然带余除法可以优化到 \(O(n\log n)\),但是此处不是复杂度瓶颈,无必要。
总时间复杂度 \(O(n^2(n+\log m))\) 。
有标号边双连通无向图计数,点数 \(n\leq 3\times 10^5\)
先考虑求带标号连通无向图的数量,设其 \(EGF\) 为 \(F(x)\),另外设不要求连通时的 \(EGF\) 为 \(G(x)\),显然有
设 \(H(x)\) 为有标号边双连通无向图数量的 \(EGF\),注意到任意一个连通图都可以通过 \(E-DCC\) 缩点变成树的形态,这里我们钦定节点 \(1\) 所在的边双为根,枚举其大小为 \(s\),然后枚举与根相连的子树的大小 \(a_1,..,a_m\),枚举子树到根的连边方式,有
设 \(F_1(x)=xF'(x)=\sum_{n\geq 0}\frac{nf_n}{n!}\)
根据拉格朗日反演
\([x^0]F(x)=[x^0]G(x)=0\),\(F(x)\) 和 \(G(x)\) 互为复合逆,即 \(F(G(x))=G(F(x))=x\),则有
\[[x^n]H(G(x))=\frac{1}{n}[x^{-1}]\frac{H'(x)}{F(x)^n} \]证明可见 有关拉格朗日反演的扩展形式的证明
可以发现这等价于 \(F(G(x))=H(x)\) 时
\[[x^n]F(x)=\frac{1}{n}[x^{-1}]\frac{H'(x)}{G(x)^n} \]
设 \(P(x)=x\exp(F_1(x))\),则
从而
于是多项式 \(\exp\) 加多项式求导即可,时间复杂度 \(O(n\log n)\) 。
给定 \(F(x)=\sum_{i=0}^n f_ix^i\) 和 \(k\),对于 \(1\leq p\leq n\),求出 \([x^k]F(x)^p\) 。
先考虑 \(F(x)\) 的常数项 \(f_0=0\) 的情况,设
设 \(G(x)=F^{-1}(x)\),根据拉格朗日反演
所以
所以我们只要求出 \(\left(\displaystyle\frac{x}{G(x)}\right)^k\),然后利用每一项就可以快速求出答案,在求出 \(G(x)\) 之后的时间复杂度是 \(O(n\log n)\) 的。
\(F(x)\) 常数项非 \(0\) 时,令 \(F_0(x)=F(x)-f_0\),然后求出 \([x^k]F_0(x)^p\),而
是一个卷积的形式,\(FFT\) 即可。
直接求 \(F(x)\) 的复合逆可以做到 \(O((n\log n)^{1.5})\),practical 的 做法 有 \(O(n^2+n\sqrt n\log n)\) 的。不过如果 \(F(x)\) 有比较好的性质,能快速求出 \(G(x)\) 的话,剩下部分可以 \(O(n\log n)\) 完成。