多项式计数
Matrix - Tree 定理
需要知道的一些线性代数知识
线性相关
考虑 \(n\) 个向量 \(v_1,v_2\dots v_n\),如果存在 \((a_1,a_2,\dots a_n)\neq 0\) 满足 \(a_1v_1+a_2v_2\dots =0\) 那么称这 \(n\) 个向量线性相关,反之为线性独立。
行列式
对于一个 \(n\times n\) 的矩阵 \(A\)。
性质
- 将第 \(i\) 列 \(\times a\) 加到第 \(j\) 列,\(\det(A)\) 不变。
- 交换两列,行列式值取反。
- 某列全体 \(\times a\),\(\det\) 变大 \(a\) 倍。
以上三个可以根据定义得到,并且对于行也成立。
同时行列式满足 \(\det(A)=\det(A^T)\)。如果 \(\det(A)\neq 0\),那么所有列向量是线性无关的。
计算方式
观察三角矩阵的 \(\det\)。会发现其值为 \(\prod a_{i,i}\)。
考虑如果做一个类似高斯消元的过程让行列式变成三角矩阵。
可以讲一下大概怎么做,其实是非常平凡的,我们考虑一列一列消。对于第 \(i\) 列,只保留 \([1,i]\) 行的内容。通过第一条性质可以轻松做到,举例:
先消第一行,那么对于第二行加上第一行所有的数 \(\times -\dfrac{1}{2}\) 的结果,第三行加上第一行所有的数 \(\times -1\) 的结果,得到:
然后对于第二列做一样的操作,会发现因为前面都是 \(0\) 了,那么这些数是不会影响操作的。最后就会形成一个三角矩阵。
在需要取模非质数的时候,可以进行两行辗转相减,不做赘述。
矩阵树定理
对于图 \(G=(V,E)\),考虑
定义 \(Q\) 矩阵,满足:
- \(Q_{i,i}=deg_i\)
- \(Q_{i,j}=-1,i\neq j,(i,j)\in E\)
- \(Q_{i,j}=0,i\neq j,(i,j)\not\in E\)
令 \(M_{1,1}\) 为删掉 \(Q\) 中的第一行第一列,则 \(G\) 中的生成树个数就等于 \(\det(M_{1,1})\)。
\(Q\) 矩阵还有一个名字即 Kirchoff 矩阵。还可以写成 \(Q=D-A\),\(D\) 为度数矩阵 \(A\) 为图的邻接矩阵。
如果有重边同样成立,将 \(-1\to -cnt\),\(cnt\) 为之间的边数即可。
而且 \(M_{i,i}=M_{j,j},i,j\in[1,n]\)。
证明
证明是比较重要的, 因为后面题目需要用到一些证明的思想。
定义矩阵 \(E\),其有 \(n\) 行 \(m\) 列,满足 \(i\) 列的 \(u\) 项为 \(1\),\(v\) 项为 \(-1\)。其中 \((u,v)\) 为 \(i\) 条边连接的点。
那么有 \(E\times E^{T}=Q\),这个是好证明的。
令 \(F\) 为 \(E\) 删掉第一行的矩阵,那么有
第二部运用了 Cauchy–Binet formula,即对于 \(n\times m\) 矩阵 \(A\) 和 \(m\times n\) 矩阵 \(B\),\(\det(AB)=\sum_S\det(A_S)\det(B_S)\) 其中 \(S\) 表示 \(\{1,2,\dots m\}\) 的大小为 \(n\) 的一个子集。\(A_S\) 表示取出这些对应列组成的矩阵,\(B\) 是取出这些对应行组成的矩阵。这里带入 \(F,F^{T}\) 会发现 \((F_S)^T=(F^T)_S\),也就是说这两个的行列式是一样的,通过上面的行列式的性质可以得到。
引理:\(S\) 相当于在 \(m\) 里面选择 \(n-1\) 条边。会发现,\(\det(F_S)=\pm 1\) 当且仅当 \(S\) 构成生成树,否则 \(\det(F_S)=0\)。
如果 \(S\) 存在环,那么显然这个环上面的所有边构成的列向量加起来是 \(0\),也就是说 \(\det(A)=0\)。对于第一部分的证明,可以感性观察,注意到交换行列不会影响行列式的绝对值,因此可以构造出来三角矩阵,且斜对角全部是 \(-1\)。
也就是说 \(\sum_S\det(F_S)^2\) 就是对于生成树计数。
用法以及技巧
带权树
矩阵树可以求的是:
同样还可以求:
可以把边的权值视为有 \(w_e\) 条重边,发现每一个生成树相当于没有重边的版本乘上权值。将对应的 Kirchoff 矩阵修改即可。
一些 DFT / IDFT 的算法
学多项式是一个很有意思的过程。开始的时候你会学习 FFT / NTT 知道怎么样通过 DFT / IDFT 快速计算多项式的各种操作。然后你会深入学习多项式的各种运算,比如求逆、\(\exp,\ln\) 等等。然后你会到这一个部分,你发现又回到了 DFT / IDFT 的一些操作之中,但是再次看这些东西的时候,你其实比刚开始学的时候有了更为深入的理解。有一种“反其本矣”的奇妙感觉。
Bluestein
一般在做 DFT 的时候,会将给定的多项式变成 \(2^k\) 长度来操作,考虑这样一个问题:
给定 \(A(x)\),求 \(A(x)\) 在 \(\omega^0,\dots,\omega^{n-1}\) 位置的点值。
转化,对于 \(b_0\dots b_{n-1}\),令 \(b_m=\sum_{k=0}^{n-1}a_k\times (\omega^m)^k\),有一个小技巧:
通过这个来整理一下式子,能够得到:
后面两个东西看起来很像一个卷积的形式,但是不标准,因为和事 \(m+1\)。经典平移一下,令 \(B_{m+n}=\omega^{-\frac{1}{2}m^{\underline{2}}}b_m\),\(A_k=a_k\omega^{\frac{1}{2}(k+1)^{\underline{2}}}\),再令 \(C_j=\omega{-\frac{1}{2}(j-n)^{\underline{2}}}\),让 \(A_v=0,v\in[n,m+n]\) 能够得到:
这就是标准卷积形式,其中的 \(A,C\) 都是很好得到的。
注意在小技巧部分,如果用 \(2mk=m^2+k^2-(m-k)^2\) 看起来能够得到结果,但是这会导致 \(\sqrt{\omega}\) 的出现,这要求存在二次剩余。
Bluestein 还有一个优势就是可以做等比多点求值,且是 \(\mathcal{O}(n\log n)\),比直接多项式多点求值要快。
I:JDU-4656
题面
给定 \(a,b,c,d\),令 \(F(x)=\sum_{i=1}^{n-1}a_ix^{i}\),\(\forall k\in[0,n)\) 求 \(F(b\times c^{2k}+d)\)。取模 \(10^6+3\)。
Sol
先推一下式子:
令 \(p_j=\sum_{i=j}^na_ii!\dfrac{d^{i-j}}{(i-j)!}\),这看起来就很能卷机的样子,搞一搞可以弄成:\(p'_{n-j}=\sum_{i=0}^{n-j}f_{n-i-j}g_i\) 的形式。
对于前面那个东西,回顾一下刚才的东西,令 \(\omega = c^{2k}\) 就是一个等比多点求值的过程了。
注意这题要 MTT。
单位根反演
核心式子:
证明需要回顾一下单位根的性质,在多项式小记里面有,都是非常基础的。
- 如果 \(k\bmod n=0\),此时有 \(\omega^{ik}=1\) 右边等于 \(\dfrac{1}{n}\times n=1\) 等于左边。
- 如果 \(k\bmod n \neq 0\),此时右边是等比数列求和,结果为 \(\dfrac{\omega_n^{kn}-1}{\omega_n^k-1}\),分子等于 \(0\) 且分母不等于 \(0\)。结果就是 \(0\)。
这个是处理形如“只保留某个数的倍数项”问题的利器。直接来看例题。
II:白兔的 ?难
cnblogs 你这屏蔽我?
题面
给定 \(n,k\) 求:
\(n\le 10^{10^6},k=2^m,m\le 20\)。
Sol
进行单位根反演:
套路地交换求和项,然后进行一些提取。
对于 DFT / IDFT 比较熟悉的选手能够看出来这部分就是一个 IDFT 过程(因为这刚好是一个 \(2^v\) 的多项式)就是我们在知道了点表示法然后转回到系数表示法的过程,这个在多项式小记里面也有式子。写起来是比较简单的。
来看一道综合一点的套路题,也是可爱的兔子。
III:白兔之舞
题面
给定 \((L+1)\times n\) 个点,可以理解为 \((L+1)\) 行 \(n\) 列。对于一对点 \((u_1,v_1),(u_2,v_2)\) 若 \(u_2>u_1\) 则 \((u_1,v_1)\to (u_2,v_2)\) 之间有 \(W[v_1][v_2]\) 条不同的边。其他情况没有边。现在给定 \(x,k,y\),有一只兔子从 \((0,x)\) 开始,终点在 \((?,y)\)。对于所有 \(0\le t<k\),求有多少条不同的路径满足其长度 \(len \bmod k=t\),答案 \(\bmod p\)。
\(n\le 3,L\le 10^8,1\le k\le 65536,p\in prime,k|(p-1)\)。
Sol
先考虑固定长度 \(i\) 有多少种从 \((0,x)\to (?,y)\) 的方案,令这个问题答案为 \(f_i\)。对于行,相当于选择一些行去走,即 \(\binom{L}{i}\),行和列是独立的,令 \(G\) 为开始时候的矩阵,那么列的情况就应该是 \(G\times W^i\) 的第 \(y\) 项,下面记为 \((G\times W^i)_y\)。经典传球问题。那么有 \(f_i=\binom{L}{i}\times (G\times W^i)_y\),接下来就可以开始推式子了,令答案为 \(ans\):
这里已经看到胜利的曙光了,但是这个题有点问题在于并没有保证 \(L=2^v\) 不能走捷径,但是问题也不大,相当于要长度不为 \(2^v\) 的单位根的点值,老老实实用 Bluestein 做。但是还要注意要写 MTT,因为模数不确定。
感觉这题的评分点全在套路上了,推式子就是纯套路。
循环卷积
这部分的定义需要注意一下,不要和普通的线性卷积混淆。循环卷积如其名,为:
我们一般写 DFT 的时候一般会有这样一步操作:
for(;n<sizX+sizY;n<<=1);
也就是说平时的时候我们做 DFT / IDFT 的时候实际上我们是取模了 \(2^v\)。但是有时候,题目会让我们去做一个 \(n\) 次意义下的循环卷积。你说,这很简单,我帮两个多项式乘起来,然后做一个 \(\mathcal{O}(n)\) 的加法实现循环卷积的功能。听起来很好,但是这个做法有不小隐患,来看一个例题。
IV:P4191
题面
给定两个 \(n\) 次多项式 \(A,B\),和一个数字 \(c\),求 \(A\times B^c\),其中乘法的定义为 \(n\) 次循环卷积。取模 \(n+1\),保证 \(n+1\) 是一个质数。
Sol
这时候上面 naive 的做法就不太行了,需要知道一个定理:
两个 \(n\) 次多项式的 \(n\) 次循环卷积等于他们 DFT 之后系数相乘再进行 IDFT 得到的结果。
这个定理在之前 FFT 的时候,我们是用“点表示法”来理解的。现在我们还可以用单位根反演来证明它,这里就先暂时略过。这个定理的用处在于,如果我们能够求出来 \(B\) 的 DFT 形式,对于每一个数做一次快速幂,然后做一次 IDFT 就可以得到 \(B^c\) 在 \(n\) 次意义下的循环卷积。
回顾我们在做 DFT 的时候要做什么,在 \(\omega^{0\to n-1}\) 的地方求点值。这时候我们 \(n\) 变得一般化了,这意味着要干什么?Bluestein 直接干就对了。
但是这个题目还有一个条件,保证输入的 \(n\) 能够分解成若干个不超过 \(\le 10\) 的数的乘积。运用这个条件,我们可以换一种方法试一试。
在正常的 FFT 中,我们有两个个关键的式子:
\(F(ω^{k+n/2}_n)=F_e(ω^{k}_{n/2})-ω^k_nF_o(ω^{k}_{n/2})\)
\(F(ω^k_n)=F_e(ω^k_{n/2})+ω^k_nF_o(ω^k_{n/2})\)
也就是说,我们通过把多项式分成奇偶两个部分,让两个部分分别只算 \(\frac{n}{2}\) 个点值,然后如此递归下去,最后只需要做若干个长度为 \(1\) 的多项式求一个点值。这样的复杂度就是 \(\mathcal{O}(n \log n)\)。
这个思想是可以推广的,对于一个普通的 \(n\),如果其有因子 \(d\),那么有仍然可以拆分成 \(d\) 个多项式求点值的结果,具体地:
如果 \(n\) 是一个大质数,那么无法这样进行分解,只能做 \(n\) 次暴力点值,是非常糟糕的。但是由于 \(n\) 最大的质因子为 \(7\),也就是说最后需要暴力做的长度最多是 \(7\),就可以通过这个小技巧不用 Bluestein 的推导同样做出来。
例题
P3746
题面
求
其中 \(n,k,r,p\) 给定 \(r<k\le 50,n\le 10^9\),\(p\le 2^{30}\)。
Sol
如果你跟我一样一眼看不出答案就老老实实单位根反演,得到的结果是:
同样发现这是一个反演的式子,令 \(F_r\) 等于其,那么 \((1+ \omega_k^j)^{nk}\) 就是 \(F\) 在 \(\omega_k^j\) 位置的点值。也就是说 \(F_i=[x^i](1+x)^{nk}\) 注意这里应该是在 \(k\) 次意义下的循环卷积乘法,通过单位根的性质能够得到。需要特判 \(k=1\),因为这时候 \((1+x)\) 本身就超过长度了,应该是 \(2\).
Loj6475
题面
给定 \(n,s,a_0,a_1,a_2,a_3\),求:
多测,\(T\le 10^5,n\le 10^{18},s,a\le 10^8\)。
Sol
显然要拆贡献,得到:
注意到因为模数是给出来的,则 \(\omega_4^1=g^{\frac{p-1}{4}}\) 就有 \(\mathcal{O}(16\times T\log n)\) 的复杂度。
P5591
题面
求:
其中 \(n,p\le 998244353,k\le 10^6,k=2^v\)。
Sol
这题需要一定的转化,向下取整式非常头疼的,向下取整在莫反里面用到的比较多,但这个题和数论函数关系不大。知道 \(\lfloor \frac{i}{k}\rfloor=\frac{i-i\bmod k}{k}\),可以开始代换,我试了一下拆贡献,是可以做但是会让题目变得比较复杂,到后面要用白兔之舞的技巧,而且还需要稍微卡常,不拆贡献直接先一起考虑更好,对于后面需要取模的部分再拆贡献(需要用到:\(m\binom{n}{m}=n\binom{n-1}{m-1}\)
后面的部分经典循环卷积,题目很善良地给了 \(k=2^v\),因此直接做一次 NTT,然后每一个位置做一个 \(n\) 次幂,然后拉回来 \(\times r\) 即可。前面的更简单,直接数字运算。
各种 FFT 的套路 + 一些线性代数
FFT 套路
AVL-Tree
转移:
求 \(\omega^0\to \omega^{65535}\) 即可,不用 NTT,最后还原。
Buying snacks
转移:
分情况讨论得到的结果。
由于 \(n\) 太大,点值不够求 \(F_n(x)\) 的系数。
考虑矩阵快速幂:
相当于求 \(A^n\),中间用多项式乘法。注意优化(减少 DFT / IDFT 的次数)。
复杂度双 \(\log\)。
Poland Ball
转移:
即
矩阵快速幂同样可以双 \(\log\)。
令 \(G(z)=\sum_{i=0}^n F_iz^i\)。
有 \(G(z)=\dfrac{1}{1-(1+x)z-xz^2}\),之后化成 \(G(z)=\dfrac{u}{1-Az}+\dfrac{v}{1-Bz}\) 的形式。其中 \(u,v\) 只和 \(A,B\) 相关,\(A,B\) 只和 \(x\) 相关。
得到 \([z^n]G(z)=\dfrac{A^{n+1}-B^{n+1}}{A-B}\) 全家桶并用,能做到 \(\mathcal{O}(k \log k)\) 因为只用保留 \(k\)。
Unlucky string(改)
给定 \(n,m,k\) 有 \(m\) 个字符,给定一个长度为 \(k\) 的字符串 \(S\)。求有多少个长度为 \(n\) 的字符串满足其中不含 \(S\) 为字串。\(n,m,k\le 10^5\)。
令 \(f_i\) 表示有多少个长度为 \(i\) 且后缀恰好为 \(s\) 且前面都没有出现过 \(s\)。
\(i<k\to f_i=0\),反之则:
令 \(d(x)=\sum_{i\in border(S)}x^i\)
验证起来是比较简单的,要学习正推。
答案为 \(m^n-\sum_{i=0}^nf_im^{n-i}\)
优化齐次线性递推方程
若 \(f\) 满足:
若 \(k\le 32000,n\le 10^9\) 求 \(f_n\)?
直接用矩阵快速幂大概是 \(\mathcal{O}(k^3\log n)\) 的算法,无法满足。
但是还是可以构造出来矩阵:
特征多项式
记:
其实就是转移矩阵 \(M\) 的特征多项式,关于 \(M\) 的特征多项式,定义方式为:
对于上面式子左侧的结果就是:
用代数余子式计算,能够得到这个行列式算出来就是上面的 \(\Phi(\lambda)\)
Cayley - Hamilon 定理
有 \(\Phi(M)=0\)。
证明是超纲的,有空补。
优化
设 \(x^n=P(x)\times \Phi(x)+r(x)\),即带余除法。则:
有 \(r(M)=\sum_{i=0}^{k-1}r_iM^i\)
令
有 \(F_{n+k-1}=M^nF_{k-1}\) 稍微注意这个最开始矩阵快速幂左边向量的区别。代入有:
则
这个是可以 \(\mathcal{O}(k)\) 算出来的。问题在 \(r(x)\) 需要 \(\mathcal{O}(n\log n)\) 做带余除法,但是注意到 \(x^n\) 这个形式是简单的,令 \(a+b=n\),有:
分治下去,可以做到 \(\mathcal{O}(k\log k\log n)\)。
更多多项式技巧
多项式平移
若 \(F(x)=\sum_{i=0}^na_ix^i\),求 \(F(x+c)\)。
想要求后面的东西
其中 \(a'_j=a_{n-j}(n-j)!\) 再令 \(ans'_i=ans_{n-i}\),就有标准形式卷积了。
FFP
FFP 指下降幂多项式。是形如 \(F(x)=\sum b_ix^{\underline{i}}\) 的多项式。
平移
有下降幂的二项式定理:
同理 \(ans'_i=\sum_{j+k=i}b'_j\dfrac{c^{\underline{k}}}{k!}\)
连续点值 \(\Leftrightarrow\) FFP 系数
FFP 是处理连续点值的利器,包括连续点值求和等等。考虑有 \(f(x)\) 在 \(0\sim n\) 的点值为 \(y_0\sim y_n\)。又知道 \(f(x)=\sum_{i=0}^nb_ix^{\underline{i}}\) 这两者如何转化。
\(b\to y\)
有
\(y\to b\)
根据上面那个所以综合得到 \(\hat{y}(x)=b(x)e^x\bmod x^{n+1}\Leftrightarrow b(x)=e^{-x}\hat{y}(x) \bmod x^{n+1}\)
如果是给定 \(c\sim c+n\) 的时候,通过平移即可。
StirlingNumber
具体内容在这里曾经写过。这里讨论如何快速求一行、一列的 StirlingNumber。
第一类 - 行
转求 \(x^{\overline{n}}\) 的系数,令 \(f_n(x)=x^{\overline{n}}\) 注意到 \(f_{2n}(x)=f_n(x)f_n(x+n)\) 通过平移和卷积可以快速做出来。
第二类 - 行
可以用类似的求下降幂系数,还可以用通项公式,即
这就是一个简单的标准卷积的形式。
第一类 - 列
有 \(\begin{bmatrix}n\\1\end{bmatrix}=(n-1)!\) 考虑 EGF 形式,有 \(\sum_{n>0}\dfrac{x^n}{n!}(n-1)!=\sum\dfrac{x^n}{n}=\hat{A}(x)\)
考虑到斯特林数的意义,可以得到答案就是 \(\dfrac{1}{k!}\hat{A}^k(x)\)
第二类 - 列
同理,有其 EGF 为 \(e^x-1\),那么答案就是 \(\dfrac{1}{k!}(e^x-1)^k\)。
Stirling 反演 + snake oil method
Stirling 反演
反演公式
证明不是非常难,代入形式变量 \(x\) 之后研究幂次的系数等,这里略。为了方便,可以用矩阵刻画。令 \(A_{n,k}=\begin{bmatrix}n\\k\end{bmatrix},A'_{n,k}=(-1)^{n-k}\begin{bmatrix}n\\k\end{bmatrix}\),\(B\) 同样对于第二类定义。
有 \(BA'=A'B=I\)。
定理
Part I
证明:把两个函数看作向量,那么 \(\overrightarrow{f}=A\overrightarrow{g}\Leftrightarrow\overrightarrow{g}=B'\overrightarrow{f}\)。
显然将其中的第一类和第二类斯特林数对换也是成立的。
Part II
证明:\(\overrightarrow{f}=A^T\overrightarrow{g}\Leftrightarrow \overrightarrow{g}=B'^T\overrightarrow{f}\)
其中因为 \(AB'=I\) 有 \(A^TB'^T=I^T=I\)。
例题 TC-13444
给定 \(n\) 行 \(m\) 列的矩阵,每个位置填 \(1\sim c\) 的数,要求:
- 任意两行不一样
- 任意两列不一样
求方案数 \(n,m\le 5000,c\le 10^9\)。
固定行,对于前 \(m\) 列,令 \(g(m)\) 表示满足第一个限制,\(f(m)\) 表示答案。
\(g(m)=(c^m)^{\underline{n}}\) 又知道 \(g(m)=\sum\limits_{i=0}^m\begin{Bmatrix}m\\i\end{Bmatrix}f(i)\) 直接反演:
可以不用多项式算 Stirling。
带权连通图计数问题
\(n\) 个点的带标号完全图 \(K_n\),令其所有联通子图的总权值为 \(W_n\)。权值定义如下
\(w(G)=a^{|E(G)|}\)
- 法 1:EGF
定义 \(\hat{F}(x)=<W_0,W_1,\dots W_n>,\hat{G}(x)=<g_0,g_1,\dots g_n>\),其中 \(g_n\sum_{E\subseteq K_n}a^{|E|}\)。
注意到其中
直觉上告诉我们 \(\hat{G}(x)=\exp(\hat{F}(x))\),因为任意一个图是由若干个连通图构成的。证明:
定义
因此 \(g_{n,k}\) 的 EGF 系数为 \([x^n]\dfrac{1}{k!}\hat{F}^k(x)\),又本来的 \(g_n=[x^n]\sum g_{n,k}\),因此:
Q.E.D.
那么答案 \(\hat{F}(x)=\ln \hat{G}(x)\)。特别的,当 \(a=-1\) 的时候会发现 \(\hat{G}(x)=1+x\),则此时 \(W_n=(-1)^{n-1}(n-1)!\)。这个可以当作定理记忆。
有 \(\mathcal{O}(n\log n)\) 的复杂度
- 法 2:Stirling 反演
定义对于 \(n\) 个点的一个划分 \(\pi\),定义:\(f(\pi)\) 满足所有的 \(G\) 其中每一个划分里面是联通的,但是划分与划分之间是不联通的权值和。\(g(\pi)\) 是所有只需满足划分与划分之间不联通的 \(G\) 的权值和。再令:
\(f_k=\sum_{|\pi|=k}f(\pi),g_k=\sum_{|\pi|=k}g(\pi)\)。
观察
证明:考虑每一个 \(f_i\) 对于 \(g_k,k\le i\) 的贡献,相当于把所有联通块放到 \(k\) 个盒子里面,系数就是第二类斯特林数。
要求的
剩下就在求 \(g\),先看看 \(a=-1\) 的特殊情况。会发现 \(g_k=1\) 当且仅当 \(k=n\) 其他情况都是 \(0\)。因为 \(k\neq n\) 的时候,一条边可以被抵消。这样算出来答案同样是 \(W_n=(-1)^{n-1}(n-1)!\)。
一般的,用 dp 来解决,令 \(dp_{n,i}\) 表示 \(n\) 个点分成 \(i\) 块连边求和的答案。
经典枚举 \(1\) 在哪里。关于 \(k\) 可以预处理,因此有一个 \(\mathcal{O}(n^3)\) 的算法。
\(w(G)=[E(G)=m]\)
这部分只能用 Stirling 反演。前面的定义都是一样的,现在目标是算出来 \(g_k\),直接在 dp 上入手。
令 \(dp_{a,b,c}\) 表示 \(a\) 个点 \(b\) 个块 \(c\) 条边(满足只在块内连边)。
但是看一看这个状态情况,状态就是 \(\mathcal{O}(n^4)\),继续用上面的转移方法,会发现是惊人的 \(\mathcal{O}(n^7)\)。也就是说只能解决 \(10\) 个点的情况,非常糟糕。
优化(比较复杂)
这部分是完全 dp。
先写出来:
“思维不要被限制”
观察
考虑后面 \((-1)^{i-1}(i-1)!g_k\) 怎么求。
其等价于这样一个问题:
先把所有点分成 \(B_1,\dots B_i\) 个块,其有序,并且 \(1\) 必须在 \(B_1\) 当中【提供了 \((i-1)!\) 的系数】,之后在块里面连接 \(m\) 条边【限制条件】,最和这个图的情况贡献是 \((-1)^{i-1}\)【提供最后一个系数】。
这时候可以定义一个新的 dp。令 \(dp_{a,c}\) 表示分成若干个块,块内总边数为 \(c\)。这样就成功优化掉了一个维度。
初始 \(dp[x][\binom{x}{2}]=1\)。
注意到是块内总边数为 \(c\),最后乘上系数 \(\binom{c}{m}\) 去得到答案。
例题
给定 \(G_1,\dots ,G_s\) 满足都是从 \(n\) 个点上的完全图取出来的一个子图。求有多少种选择若干个 \(G\) 的方法满足这些图的异或图是联通的。\(s\le 60,n\le 10\).
定义 \(x\) 表示一种选择方法,\(G_x\) 表示这种选择方法的异或图。定义 \(f(\pi)\) 为有多少个 \(G(x)\) 满足划分情况为 \(\pi\),限制和上面一样。\(g(\pi)\) 同理。其中 \(f_k,g_k\) 和上面一样还是有斯特林反演。
注意到可以枚举 \(\pi\) 其最多就是 \(Bell(10)\),然后具体判定就是一个线性基的问题。
不相等计数问题
选择 \(n\) 个数,满足 \(x_i\in S_i\),\(S\) 已知。且 \(x_1\dots x_n\) 互不相等。
令 \(m=\binom{n}{2}\)。
考虑构造 \(m\) 条边,设 \((u,v)=e\) 之后 \(A_e\) 表示选择 \(x_u=x_v\) 这样的满足第一个条件的方案数。
那么答案就是
定义一个集合 \(C\subseteq\{1,n\}\) 定义 \(h(C)\) 表示 \(\{S_i|i\in C\}\) 交集的大小。
再次转化,其中注意到 \(C\) 只和 \(\pi\) 有关系。
最后面一堆相当于是在每一个划分里面都要构造联通图,切贡献是 \(-1\) 的边数。这就是之前那个定理,因此定义 \(w(C)=h(C)\times (-1)^{|C|-1}\times (|C|-1)!\)。
直接用状压 dp,可以做到 \(\mathcal{O}(n^3)\)。但是这里还可以更优,这里
这个是一个子集卷积的 \(\exp\),会在后面再讲。也就可以做到 \(2^n\times n^2\)。
其实这个题和 Stirling 反演没有什么关系,但是注意到这个容斥过程。在 \(f,g\) 中 \(g\) 是去掉了 \(f\) 块内联通的条件,这个题说明了如果去掉 \(f\) 块之间不能连边的条件可以通过容斥反回去。
Snake Oil Method
看到名字的时候觉得莫名其妙的,去查了一下才知道 snake oil 就是万金油的意思。
snake oil method 就是一个对付组合数求和的非常厉害的工具。
That one method is capable of handling a great variety of sums involving binomial coefficients, but there’s nothing special about binomial coefficients in this respect.
看一个例子:
如果先尝试手玩一下可能能发现这就是斐波那契数列。下面来看一下 Snake Oil 怎么解。
先构造出来一个多项式 \(A(x)\) 满足 \(a_n=\sum\limits_{k=0}^n\binom{k}{n-k}\),尝试求其的母函数,展开:
会发现得到的结果就是斐波那契的母函数,后面也就不继续下去了。也就是说 \(A(x)\) 就是 Fib 的生成函数。
Snake Oil 的基本方法就是放到生成函数中,交换求和顺序,然后尝试解出来里面的东西。有一些比较常见的代换式可以用到:
尝试解:
这个就不好一眼看出来了
这样就是比较方便求出来 \(x^n\) 的系数了,做两个减法即可。
综合习题、欧拉数、IDFT+
综合习题
数幂求和 I
给定 \(n,m\),求 \(\forall i\in [0,m],s_i=\sum_{x=0}^{n-1}x^i\)。
方法 0
用斯特林可以得到:
这样只有一个 \(\mathcal{O}(n^2)\)。
方法 1
令 \(\hat{S}(x)\) 为 \(<s_0\dots s_m>\) 的 EGF。
用多项式求逆,注意的是两个的常数项都是 \(0\)。这种时候要都提出一个 \(x\),分母是 \(-\sum_{i\ge 1}\dfrac{1}{i!}x^i=-x\sum_{i\ge 0}\dfrac{1}{(i+1)!}x^i\)。分子是 \(-\sum_{i\ge 0}\dfrac{n^{i+1}}{(i+1)!}x^{i+1}=-x\sum_{i\ge 0}\dfrac{n^{i+1}}{(i+1)!}x^i\)。要求的都是前 \(m\) 项,因此复杂度是 \(\mathcal{O}(m\log m)\)。
与伯努利数的关系
前面的 \(\dfrac{x}{1-e^x}\) 就是伯努利数的系数。
方法 2
让我想到梅加强老师的《数学分析》当中提到的一个技巧——做差。
考虑:
对于 \([1,n]\) 都做出来这个,之后会不断抵消,最终:
幂数求和 II
改一下:\(s_i\sum_{x=0}^{n-1}a_x^i\),其中 \(a\) 给定。
直接用 EGF 可以得到一个:
但是这个并不好做。
考虑直接用 OGF,能够得到:
定义
注意到 \(Q(x)\) 就是分母,\(P(x)\) 就是分子。现在就是要分别求,都可以使用分分治 FFT。具体的,定义 \(Q_{l,r},P_{l,r}\)。\(Q_{l,r}=Q_{l,mid}\times Q_{mid+1,r}\) 而 \(P_{l,r}=P_{l,mid}\times Q_{mid+1,r}+P_{mid+1,r}\times Q_{l,mid}\)。
这个就是 \(\mathcal{O}(m\log^2m)\)。
应用
对于一个多项式 \(H(x)\) 系数给定了,求 \(H(a_0x)+H(a_1x)+\dots H(a_{n-1}x)\)。
如果交换求和顺序就有答案:
这个就是刚才的东西。
例 1
有多少个非负整数 \((x_1\dots x_m)\) 前 \(n\) 个数小于等于 \(t\) 并且所有数的和 \(\le s\)。\(S\le 10^{18},n\le 10^9,n\le m\le n+1000\)。
考虑先枚举出来前面的 \(n\) 个数,剩下的限制形如:\(x_{n+1}+\dots x_m\le S\),这是经典组合数。因此答案为:
令 \(T=s+m-n,z=T-(x_1+\dots x_n)-(m-n)+1\),答案可以写成:
前面都是好求的,关键在于后面的东西,令 \(s_0=T-(m-n)+1\):
代回:
定义 \(g(i)=0^i+\dots t^i\)。
定义 \(G(x)=\sum_{i\ge 0}\dfrac{g(i)}{i!}x^i,H(x)=\sum_{i\ge 0}\dfrac{(-s_0)^i}{i!}x^i\)。
因此后面的东西就是 \([x^k]G^n(x)H(x)\)
\(g(i)\) 可以预处理,只需要一行的斯特林数,无论哪里的复杂度都是 \(\mathcal{O}((m-n)\log (m-n))\)。
P4002
IDFT 的拓展
回顾 Bluestein 我们可以给定系数求点值,而且并不在意长度是多少。观察我们得到的式子
通过卷积可以求出来 \(B\),然后取后面的若干项就可以得到答案。
不过这个做法是不可逆的。原因是我们把所有的点值是进行平移过的,也就是说单纯给定点值是不知道 \(B\) 的前面若干神秘项的。因此无法直接做除法。
点值 \(\to\) 系数
已知多项式在 \(q^0\sim q^{n-1}\) 位置的点值,求其系数。
用 Lagrange 差值有:
这个式子可以改写成,令 \(A(x)=\prod(x-q^i)\):
只需要证明 \(A'(q^i)=\prod(q^i-q^j)\) 这个是比较显然的。
问题分成三步:
1. 求 \(A(x)\)
分治 FFT,有显然的 \(\mathcal{O}(n\log^2n)\),不过因为是等比的,所以分治的时候右边多项式可以从左边推出来,因此复杂度可以少一个 \(\log\)。
2. 求 \(d_i=\dfrac{y_i}{A'(q^i)}\)
\(A'(x)\) 是好求的,剩下的就是等比求点值用 Bluestein 可以解决。
3. 求 \(\sum\limits_{i=0}^{n-1}\dfrac{d_i}{x-q^i}\)
把 \(\dfrac{1}{x-q^i}\) 拆开,然后交换求和顺序,能够有:
如果定义一个多项式 \(D(x)\) 那么后面又是一个等比求值的问题,还是可以 Bluestein。
因此总复杂度是 \(\mathcal{O}(n\log n)\) 前提是给定的是等比的。
浅看了一个随机点值,那个也是可以做的,需要知道非等比求点值(Bluestein 无法使用),然后思路基本一样,复杂度是 \(\mathcal{O}(n\log^2n)\)。
欧拉数
\(\left\langle\begin{matrix}n\\k\end{matrix}\right\rangle\) 表示长度为 \(n\) 的排列恰好有 \(k\) 次上升的方案数。
有比较显然的递推:
考虑如何快速单点求值和求一行。
下面默认求第 \(n\) 行,令 \(f_k\) 表示答案,令 \(g_k\) 表示钦定了 \(k\) 个位置是上升的。
有一个比较巧妙的观察:\(g_k=(n-k)!\begin{Bmatrix}n\\n-k\end{Bmatrix}\)。可以分析连续上升段,每一段相当于一个盒子。
因此:
用斯特林的通项公式展开,并且做一些替换:
最后一步考虑组合意义。相当于 \(n+1\) 个球先选择一个求作为分界点,剩下的左边选择 \(k\) 个右变选择 \(t\) 个。
这个公式可以快速算出来单点。其中 \(t^n\) 是积性函数可以线性算。
注意到:
如果把这个带进去,能够有:
这个是可以 FFT 的。