《欧拉数问题选讲》阅读笔记
孩子们这是我冬令营唯一听懂的内容,虽然大部分还是抄课件。
欧拉数定义
对于一个长度为 \(n\) 的排列 \(p\),我们记 \(asc(p)=\sum\limits_{i=1}^{n-1}[p_i<p_{i+1}]\),也就是 \(p\) 中上升的数量。
我们定义欧拉数 \(\left\langle\begin{matrix}n\\k\end{matrix}\right\rangle\) 为有多少长度为 \(n\) 的排列 \(p\) 满足 \(asc(p)=k\)。由于这个符号太难打所以下文我们写成 \(E(n,k)\)。
根据定义可以得出一些 dp 来求解这个问题。常见的有两种:
-
考虑在值域上扫描,往位置上插入。
设 \(f_{i,j}\) 表示当前考虑 \(\le i\) 的数字,\(asc(p)\) 当前为 \(j\) 的方案数。转移考虑 \(i+1\) 是放在上升的空隙中还是下降的空隙中。这样可以得到转移:
\[f_{i,j}=(j+1)f_{i-1,j}+(i-j)f_{i-1,j-1} \]这样可以 \(O(n^2)\) 求出所有的 \(f\)。
-
考虑在位置上扫描,往值域上插入。
设 \(f_{i,j,k}\) 表示当前考虑 \(1\sim i\) 这些位置,\(asc(p)\) 当前为 \(j\),最后一个数是前面这些数中第 \(k\) 小的方案数。转移的时候考虑下一个数是第几小的,那么我们有:
\[f_{i,j,k}\to f_{i+1,j+[k<x],x} \]直接转移是 \(O(n^4)\) 的,前缀和优化可以做到 \(O(n^3)\)。最后 \(E(n,k)=\sum f_{n,k,i}\)。
当然课件里面还有一种方法,不过实际上最终导出的就是连续段 dp,但是在欧拉数问题上这看起来并没有什么优势,所以我们就不再介绍了。
容斥原理的理解
这个课件的重头戏应该在这。我们把常见的计数问题做如下刻画:
我们假设现在要计数的对象集合为 \(A\),其中的每个元素为 \(a\)。现在对于每个元素我们有 \(n\) 个性质,设 \(f_i\) 是一个 \(A\to \{0,1\}\) 的映射,\(f_i(a)=1\) 当且仅当 \(a\) 满足第 \(i\) 个性质。
然后我们还有两个预定好的长为 \(n\) 的序列 \(p_i,q_i\),我们记一个元素 \(a\) 的权重 \(w(a)\) 为:
而我们的目标是计算 \(\sum\limits_{a\in A} w(a)\)。
看上去比较抽象,我们举一个例子来理解:
-
给定 \(n\) 个数 \(c_i\),求出 \([1,m]\) 中有多少个数不是任何一个 \(c_i\) 的倍数。
我们记 \(A=\{1,2,\cdots, m\}\),而 \(f_i(a)=[c_i\nmid a]\)。我们令 \(p_i=1,q_i=0\),这样我们的 \(w(a)\) 为 \(1\) 当且仅当所有的 \(f_i(a)\) 均为 \(1\),也就是 \(a\) 不是任何一个 \(c_i\) 的倍数。求和后就是我们要求的值。
这个问题的做法是熟知的,下面我们从这个角度来理解它。
将上面的式子变形得到:
如果我们记 \(U\) 表示所有满足 \(f_i(a)=0\) 的 \(i\) 构成的集合,那么上面的式子可以写成:
我们现在改为枚举 \(S\),那么 \(w(a)\) 有这一项当且仅当对于所有 \(i\in S\) 有 \(f_i(a)=0\)。那么如果我们记 \(cnt(S)\) 表示有多少 \(a\in A\) 满足 \(\forall i\in S,f_i(a)=0\),则可以得到如下式子:
而这就是容斥原理。看上去非常奇怪,这并没有出现我们常见的 \((-1)^k\) 这样的系数,我们还是看上面的例子。
- 由于 \(p_i=1,q_i=0\),所以我们有 \(q_i-p_i=-1\)。那么代入公式可以得到:\[\sum_{a\in A}w(a)=\sum_{S\subseteq\{1,2,\cdots,n\}}(-1)^{|S|} cnt(S) \]而这里的 \(cnt(S)\) 就是 \([1,m]\) 中满足 \(\forall i\in S,c_i\mid a\) 的 \(a\) 的数量。而这和我们传统的做法导出的结果是完全一致的。
当然了我们也可以将 \(w(a)\) 变成:
最后得出的公式是差不多的。
再次计算欧拉数
那么现在我们令 \(A\) 为所有 \(n\) 阶排列构成的集合,现在有 \(n-1\) 个限制,对于 \(a\in A\),\(f_i(a)=[a_i<a_{i+1}]\)。
而现在我们要求 \(E(n,k)\) 的话要求这个排列的限制个数是 \(k\),这个值我们认为是不固定的。因此此时的 \(p_i,q_i\) 我们不写成一个数,我们考虑利用多项式,令 \(p_i=x,q_i=1\)。那么对于一个排列 \(a\in A\),我们现在可以得到:
那么 \(E(n,k)\) 就是 \(\sum w(a)\) 的 \(k\) 次项系数。现在我们需要利用第二个变形,可以得到:
其中 \(cnt(S)\) 的定义是有多少 \(a\in A\) 满足 \(\forall i\in S,a_i<a_{i+1}\)。那么很显然在这个问题里我们不用枚举 \(S\),我们只关心 \(S\) 的大小 \(|S|\),所以可以得到:
其中 \(f_k\) 的定义是有多少个 \(a\in A\) 满足 \(\forall i\in [1,n-1]\),有至少 \(k\) 个位置是上升的方案数。
把这个问题改一下,我们把 \(n\) 个数划分成 \(n-k\) 段,每一段内部要求必须上升,段与段之间没有限制。看起来这个就是斯特林数 \(n\brace{n-k}\),但是由于 \(n-k\) 个段是有区分的,所以实际上还要乘 \((n-k)!\):
我们知道斯特林数是有通项公式的,直接代入:
我们知道求所有的 \(i^n\) 可以做到 \(O(n)\),所以我们可以做到 \(O(n)\) 求一个 \(E(n,m)\)。同时如果我们将 \(-1\) 的指数修改为 \((-1)^{n+m+i}\),那么这其实是一个标准的差卷积形式,于是此时我们可以做到 \(O(n\log n)\) 求出一行的欧拉数。
然后套用这个模型就可以做很多题了。
二项式反演
二项式反演是一种常见的容斥形式,一般问题描述为“求恰好满足 \(k\) 个条件的元素个数”,我们一般将“恰好”转化为“钦定”进行求解。下面我们用上面的容斥模型推导出二项式反演的结论。
由于我们要求恰好满足 \(k\) 个条件元素个数,所以和求欧拉数类似,我们用多项式代替 \(p_i,q_i\),令:
这样我们要求的就是 \([x^k]\sum w(a)\),我们套公式求出 \(\sum w(a)\):
其中 \(cnt(S)\) 表示钦定 \(S\) 中条件合法的元素数量。如果我们只关心 \(S\) 的大小的话可以进一步得出:
根据二项式定理提取一下 \(k\) 次项系数可得:
这就是二项式反演的结论了。

浙公网安备 33010602011771号