20240820:组合计数(2)

news/2024/10/3 17:11:29

组合数

定义:\(\begin{pmatrix}n\\m\end{pmatrix}\) 表示 \(n\) 元集的 \(m\) 元子集个数。

通项

\[\begin{pmatrix}n\\m\end{pmatrix} = \begin{cases} \dfrac{n!}{m!(n - m)!} & m \le n\\ \\ 0& \text{otherwise} \end{cases} \]

考虑其组合意义:

把所有 \(n!\) 个排列的前 \(m\) 个元素作为选出集合,每个集合被计算 \(m!(n - m)!\) 次。

二项式定理

\[(x + y)^n = \sum_{i = 0}^n \begin{pmatrix}n\\ i\end{pmatrix}x^iy^{n - i} \]

组合意义:从 \(n\) 个括号里选出 \(i\) 个给 \(x\),剩下给 \(y\)

因此第 \(n\) 行组合数的普通生成函数 \(F_n(x)\) 的封闭形式为:

\[F_n(x) = \sum_{i = 0}^n\begin{pmatrix}n\\i\end{pmatrix}x^i = (x + 1)^n \]

组合数的对称性

\[\begin{pmatrix}n\\m\end{pmatrix} = \begin{pmatrix}n\\n - m\end{pmatrix}\quad n\ge m \ge 0 \]

组合数的吸收公式

\[\begin{pmatrix}n\\m\end{pmatrix} = \dfrac{n}{m}\begin{pmatrix}n - 1\\m - 1\end{pmatrix}\quad n, m > 0 \]

递推公式

\[\begin{pmatrix}n\\m\end{pmatrix} = \begin{pmatrix}n - 1\\m\end{pmatrix} + \begin{pmatrix}n - 1\\m - 1\end{pmatrix} \]

组合意义就是讨论第 \(n\) 个元素是不是选出的第 \(m\) 个元素。

从生成函数的角度理解:\(F_n(x) = (x + 1) F_{n - 1}(x)\),对比系数得到递推公式。

组合数的行和

\[\begin{aligned} \sum_{i = 0}^n\begin{pmatrix}n\\i\end{pmatrix} &= (1 + 1)^n = 2^n\\ \\ \sum_{i = 0}^n\begin{pmatrix}n\\i\end{pmatrix}(-1)^i &= (1 - 1)^n = [n= 0]\\\end{aligned} \]

组合数的列和

\[\sum_{i = 0}^n\begin{pmatrix}i\\m\end{pmatrix} = \begin{pmatrix}n + 1\\m + 1\end{pmatrix} \]

把和式中第一个非零项 \(\begin{pmatrix}m\\m\end{pmatrix}\) 看作 \(\begin{pmatrix}m + 1\\m + 1\end{pmatrix}\)

  • \(\binom{m + 1}{m + 1} + \binom{m + 1}{m} = \binom{m + 2}{m + 1}\)
  • \(\binom{m + 2}{m + 1} + \binom{m + 2}{m} = \binom{m + 3}{m + 1}\)

以此类推得到 \(\begin{pmatrix}n\\m + 1\end{pmatrix} + \begin{pmatrix}n\\m\end{pmatrix} = \begin{pmatrix}n + 1\\m + 1\end{pmatrix} \)

范德蒙德卷积

\[\sum_{i = 0}^k\begin{pmatrix}n\\i\end{pmatrix}\begin{pmatrix}m\\k - i\end{pmatrix} = \begin{pmatrix}n + m\\k\end{pmatrix} \]

\(n + m\) 元集拆成一个 \(n\) 元集和一个 \(m\) 元集。

枚举 \(n + m\) 里面选 \(k\) 个出来的所有方案与这个 \(n\) 元集的交集 \(i\),组合意义显然。

一个很有用的公式

\[\begin{pmatrix}n\\m\end{pmatrix}\begin{pmatrix}m\\r\end{pmatrix} = \begin{pmatrix}n\\r\end{pmatrix}\begin{pmatrix}n - r\\m - r\end{pmatrix} \]

\(n\) 个里面选 \(m\) 个,再在 \(m\) 个里面选 \(r\) 个。

等价于 \(n\) 个里面选 \(r\) 个,在剩下的 \(n - r\) 个里再选 \(m - r\) 个。

容斥原理

\[\vert \bigcup_{i = 1}^nS_i \vert = \sum_{1 \le x_1 < x_2 \cdots < x_m \le n} (-1)^{m - 1}\vert \bigcap_{i = 1}^mS_{x_i} \vert \]

考虑每个元素在右式被计算几次。

如果一个元素在 \(k\)\(S_i\) 中出现,那么他会被计算 \(\sum_{i = 1}^k(-1)^{i - 1}\begin{pmatrix}k\\i\end{pmatrix} = [k\ne 0]\)

因此左边等于右边。

很多情况下要求同时满足 \(n\) 个条件的集合大小。

\(S_i\) 为不满足第 \(i\) 个条件的集合,那么答案即 \(\vert U\vert - \vert \bigcup_{i = 1}^n S_i\vert\)

无限制的格路计数

题意:给定 \(n, m \ge 0\),你一开始在原点,每次可以从 \((x,y)\) 走到 \((x + 1, y + 1)\)\((x + 1, y - 1)\),问走到 \((n, m)\) 的合法方案数。

设往右上走了 \(t\) 步,则往右下走了 \(n - t\) 步。

解方程 \(t - (n - t) = m\)\(t = \dfrac{n + m}{2}\)

如果 \(2 \not\mid n + m\),那么方案数为 \(0\),否则方案数为 \(\begin{pmatrix}n\\ \frac{n + m}{2}\end{pmatrix}\)

从生成函数的角度理解,次数代表纵坐标:

\[[x^m](x + x^{-1})^n = [x^{n + m}](x^2 + 1)^n = \begin{pmatrix}n\\ \frac{n + m}{2}\end{pmatrix} \]

反射容斥

例1:给定 \(n, m \ge 0\) 以及 \(p < 0\),你一开始在原点,每次可以从 \((x,y)\) 走到 \((x + 1, y + 1)\)\((x + 1, y - 1)\)

问不经过直线 \(y = p\) 上的点走到 \((n, m)\) 的合法方案数。

考虑用上个模型的方案数减去经过 \(y = p\) 的方案数。

对于一个经过 \(y = p\) 的方案,我们将 \(p\) 上方的路径折下来,得到一条 \((0, 2p)\)\((n, m)\) 的路径,任意新路径都能翻回去,因此这是一个双射。

则合法方案数等于 \(\begin{pmatrix}n\\\frac{n + m}{2}\end{pmatrix} - \begin{pmatrix}n\\\frac{n + m - 2p}{2}\end{pmatrix}\)

例2:给定 \(n, m \ge 0\) 以及 \(p < 0,\ q > m\),你一开始在原点,每次可以从 \((x,y)\) 走到 \((x + 1, y + 1)\)\((x + 1, y - 1)\)

问不经过直线 \(y = p\)\(y = q\) 上的点走到 \((n, m)\) 的合法方案数。

还是用总方案减去不合法的方案,问题转化为经过 \(y = p\)\(y = q\) 走到终点的方案数。

对于一条路径,如果经过 \(y = p\) 就写 'A',经过 \(y = q\) 就写 'B',如图路径写成 "BBBBAAB"。

把连续相同字符缩成一个,即 "BAB"。

每个路径都可以映射成一个字符串,字符串 “AB” 表示一条先经过 \(y = p\) 再经过 \(y = q\) 的路径,且没有其他地方与限制相交。

钦定先经过 \(y = p\) 再经过 \(y = q\) 的方案如何求?先将起点延 \(y = p\) 翻折转化为只有一条限制的情况,再延 \(y = q\) 翻折。

恰好呢?考虑上述计算方式会多计算哪些情况?

所谓 "AB",我们在计算过程中并不关心 "A" 前面有没有 "B" 以及 "B" 后面有没有 "A", "AB", "ABA"...。

也就是说,"BAB", "BABA"... 和 "ABA", "ABAB"... 都会在计算 "AB" 时被算到。

如何构造容斥系数使得每种非法情况("A", "B", "AB", "BA", "ABA"...)最后计算次数恰好为 \(-1\)

从另一个角度考虑重复计算,如果 \(T\)\(S\) 的子串,那么 \(S\) 的所有路径会在计算 \(T\) 时恰好被算一次。

对于字符串 "ABABA",其本质不同子串有 "A", "AB", "ABA", "ABAB", "ABABA", "B", "BA", "BAB", "BABA"。共 \(2\vert S \vert - 1\) 个。

我们知道 \(\sum_{i = 1}^{2\vert S\vert -1}(-1)^{i} = -1\),因此把每种字符串的容斥系数定为 \((-1)^{\vert S\vert}\) 可以恰好满足条件。

由于每增加一个字符,横坐标就要增加至少 \(q - p\) 的长度,需要考虑的字符串只有 \(O(\dfrac{n}{q - p})\)(不考虑从原点第一次到限制的距离,反正就是很少)。

卡特兰数

定义:第 \(n \ge 0\) 项卡特兰数 \(C_n\) 表示长度为 \(2n\) 的合法括号序列数。

通项

\[C_n = \begin{pmatrix}2n\\n\end{pmatrix} - \begin{pmatrix}2n\\n + 1\end{pmatrix} \]

用反射容斥解释这个式子。

左括号表示 \((x, y) \to (x + 1, y + 1)\),右括号表示 \((x, y) \to (x + 1, y - 1)\),卡特兰数等于 \((0, 0)\) 走到 \((2n, 0)\) 不经过 \(y = -1\) 的路径数。

这样映射满足了合法括号序列的充要条件:左括号 = 右括号;任意前缀左括号不小于右括号。

递推式

枚举第一个右括号之间有多少括号对:

\[C_n = \sum_{i = 0}^{n - 1} C_iC_{n -i - 1} \]

通过递推式解得卡特兰数的生成函数

\[F(x) = xF(x)^2 + 1 \implies F(x) = \dfrac{1 - \sqrt{1 - 4x}}{2x} \]

子集反演

\[\begin{aligned} f(S) = \sum_{T \subseteq S} g(T) &\iff g(S) = \sum_{T \subseteq S} (-1)^{\vert S\vert - \vert T\vert} f(T)\\ \\ f(S) = \sum_{S \subseteq T \subseteq U} g(T) &\iff g(S) = \sum_{S \subseteq T \subseteq U} (-1)^{\vert T\vert - \vert S\vert} f(T)\\\end{aligned} \]

只考虑第一个式子,第二个类似。

从左推右:

\[\begin{aligned} g(S) &= \sum_{T \subseteq S} (-1)^{\vert S\vert - \vert T\vert} f(T)\\ \\ &= \sum_{T \subseteq S} (-1)^{\vert S\vert - \vert T\vert} \sum_{R \subseteq T} g(R)\\ \\ &= \sum_{R \subseteq S} g(R)\sum_{T \subseteq S\setminus R} (-1)^{\vert S\vert - \vert T \cup R\vert} \\ \\ \end{aligned} \]

\(h(S) = \sum_{T \subseteq S} (-1)^{\vert S\vert - \vert T\vert}\)

\[\begin{aligned} h(S) &= \sum_{T \subseteq S} (-1)^{\vert S\vert - \vert T\vert}\\ \\ &= \sum_{i = 0}^{\vert S\vert} (-1)^{\vert S\vert - i} \begin{pmatrix}\vert S\vert\\i\end{pmatrix} = [S = \varnothing] \end{aligned} \]

带回原式:

\[g(S) = \sum_{R \subseteq S} g(R)\cdot h(S\setminus R) = g(S) \]

从右推左:

\[\begin{aligned} f(S) &= \sum_{T \subseteq S} g(S) \\ \\ &= \sum_{T \subseteq S} \sum_{R \subseteq T} (-1)^{\vert T\vert - \vert R\vert} f(R)\\ \\ &= \sum_{R \subseteq S} f(R)\sum_{T \subseteq S\setminus R} (-1)^{\vert T\vert}\\ \\ &= \sum_{R \subseteq S} f(R)[S\setminus R = \varnothing] = f(S) \end{aligned} \]

二项式反演

引入

错排问题:\(n\) 个人排列。第 \(i\) 个人不能在位置 \(i\),求合法排列数。

钦定 \(k\) 个人在自己位置上:

\[\sum_{k = 0}^n (-1)^k \begin{pmatrix}n\\k\end{pmatrix}(n - k)! \]

定义 \(f(n)\)\(n\) 个人的排列数,\(g(n)\)\(n\) 个人的错排数。

\[\begin{aligned} f(n) &= \sum_{k = 0}^n \begin{pmatrix}n\\k\end{pmatrix} g(k)\\ \\ g(n) &= \sum_{k = 0}^n (-1)^{n - k} \begin{pmatrix}n\\k\end{pmatrix}f(k) \end{aligned} \]

问题在于 \(f\) 能够快速计算,如何通过 \(f\) 反求 \(g\)

有组合恒等式

\[\sum_{k = 0}^n(-1)^k\begin{pmatrix}n\\k\end{pmatrix} = [n = 0] \]

说一句废话:

\[g(n) = \sum_{m = 0}^n [n - m = 0]\begin{pmatrix}n\\m\end{pmatrix} g(m) \]

\([n - m = 0]\) 用上面的恒等式带掉:

\[\begin{aligned} g(n) &= \sum_{m = 0}^n \sum_{k = 0}^{n - m}(-1)^k\begin{pmatrix}n - m\\k\end{pmatrix}\begin{pmatrix}n\\m\end{pmatrix} g(m)\\ \\ &= \sum_{m = 0}^n \sum_{k = 0}^{n - m}(-1)^k\begin{pmatrix}n\\k\end{pmatrix}\begin{pmatrix}n - k\\m\end{pmatrix} g(m)\\ \\ &= \sum_{k = 0}^{n} (-1)^k\begin{pmatrix}n\\k\end{pmatrix}\sum_{m = 0}^{n - k}g(m)\begin{pmatrix}n - k\\m\end{pmatrix} \\ \\ &= \sum_{k = 0}^{n} (-1)^k\begin{pmatrix}n\\k\end{pmatrix}\sum_{m = 0}^{n - k}g(m)\begin{pmatrix}n - k\\m\end{pmatrix} \\ \\ &= \sum_{k = 0}^{n} (-1)^k\begin{pmatrix}n\\k\end{pmatrix}f(n - k) = \sum_{k = 0}^{n} (-1)^{n - k}\begin{pmatrix}n\\k\end{pmatrix}f(k) \\\end{aligned} \]

公式

\[\begin{aligned} f(n) = \sum_{i = 0}^n\begin{pmatrix}n\\i\end{pmatrix} g(i) &\iff g(n) = \sum_{i = 0}^n(-1)^{n - i}\begin{pmatrix}n\\i\end{pmatrix} f(i)\\ \\ f(n) = \sum_{i = n}^U\begin{pmatrix}i\\n\end{pmatrix} g(i) &\iff g(n) = \sum_{i = 0}^n(-1)^{i - n}\begin{pmatrix}i\\n\end{pmatrix} f(i)\\ \end{aligned} \]

可以理解为 \(g(S)\) 只与 \(\vert S\vert\) 相关的子集反演。

实际应用中一般用第二种形式,\(f(n)\) 表示钦定 \(n\) 个的方案数,\(g(n)\) 表示恰好 \(n\) 个的方案数。

莫比乌斯反演

引入

周期问题:求长度为 \(n\) 的字符串且周期(最小循环节)恰为 \(n\) 的字符串个数,仅包含小写字母。

定义 \(f(n)\) 为长度为 \(n\) 的字符串个数,\(g(n)\) 为长度为 \(n\) 且周期恰为 \(n\) 的方案数。

\[f(n) = \sum_{d \mid n} g(n) \]

显然有 \(f(n) = 26^n\),怎么反求 \(g\)

设函数 \(\mu\) 满足

\[\sum_{d \mid n} \mu(d) = [n = 1] \]

构造一句废话然后代入:

\[\begin{aligned} g(n) &= \sum_{m \mid n} [\dfrac{n}{m} = 1] g(m)\\ \\ &= \sum_{m \mid n} \sum_{d \mid \frac{n}{m}}\mu(d) g(m)\\ \\ &= \sum_{d \mid n}\mu(d) \sum_{m \mid \frac{n}{d}} g(m)\\ \\ &= \sum_{d \mid n}\mu(d) f(\dfrac{n}{d}) = \sum_{d \mid n}\mu(\dfrac{n}{d}) f(d)\\ \end{aligned} \]

公式

\[\begin{aligned} f(n) = \sum_{i \mid n} g(i) &\iff g(n) = \sum_{i \mid n} \mu(\dfrac{n}{i}) f(i)\\ \\ f(n) = \sum_{n\mid i,\ i \le U} g(i) &\iff g(n) = \sum_{n\mid i,\ i \le U} \mu(\dfrac{i}{n}) f(i)\\ \end{aligned} \]

从子集反演的角度理解这个公式。

把每个数 \(x\) 映射成一个无限长的向量,第 \(i\) 为表示正整数中第 \(i\) 个质数在 \(x\) 中的次数。

整除关系即集合之间的包含关系。

现在目的是从 \(f(n)\) 里面减掉没有顶满(因子)的方案数。

只容斥与原数高度相差 \(1\) 的因子,减掉所有的 \(f(\dfrac{n}{p_i})\),加上所有 \(f(\dfrac{n}{p_ip_j})\),以此类推。

这同时也与 \(\mu\) 函数对应:存在平方因子(差两格)则为 \(0\);否则为 \(-1\) 的质因子个数次方。

第二类斯特林数

\(\begin{Bmatrix}n\\m\end{Bmatrix}\) 表示把 \(n\) 元集划分为 \(m\) 个互不区分的非空集合的方案数。

通项公式

先假定 \(m\) 个集合互相区分,最后除以 \(m!\)

钦定部分集合为空,然后容斥。

\[\begin{Bmatrix}n\\m\end{Bmatrix} = \dfrac{1}{m!}\sum_{i = 0}^m(-1)^m \begin{pmatrix}m\\i\end{pmatrix}(m - i)^n \]

递推式

\[\begin{Bmatrix}n\\m\end{Bmatrix} = m\begin{Bmatrix}n - 1\\m\end{Bmatrix} + \begin{Bmatrix}n - 1\\m - 1\end{Bmatrix} \]

考虑最后一个元素 \(n\) 扔到哪里。

选一个现有集合扔进去(虽然集合互不区分,但是元素互不相同);新增一个集合。

普通幂转下降幂

\[x^n = \sum_{i = 0}^x\begin{Bmatrix}n\\i\end{Bmatrix}x^{\underline{i}} \]

\(x^n\) 表示 \(n\) 个元素分配给互相区分的 \(x\) 个集合的方案数。

选出 \(i\) 个集合,\(n\) 个元素分出 \(i\) 个非空集合的方案是 \(s(n, i)\),由于集合不区分,再乘一个 \(i!\)

单位根反演

单位根:\(x^n = 1\) 在复平面上的 \(n\) 个解,其中 \(w_{n}^k = e^{i\frac{2k\pi}{n}}\)

\[[n \mid k] = \dfrac{1}{n}\sum_{i = 0}^{n - 1} w_n^{ik} \]

\(n \mid k\) 时,\(w_{n}^{ik} = 1\),右式等于 \(1\)

否则右边是一个等比数列,等于 \(\dfrac{1}{n}\times \dfrac{1 - w_{n}^{nk}}{1 - w_{n}^k} = 0\)

用于模意义下的原根也是对的。

min-max 容斥

\[\begin{aligned} \min(S) &= \sum_{\varnothing=T\subseteq S} (−1)^{\vert T\vert−1} \max(T)\\ \\ \max(S) &= \sum_{\varnothing=T\subseteq S} (−1)^{\vert T\vert−1} \min(T) \end{aligned} \]

以第一种形式为例,第 \(k\) 小的元素被计算的次数等于:

\[\sum_{i = 1}^k\begin{pmatrix}k - 1\\i - 1\end{pmatrix}(-1)^{i - 1} = \sum_{i = 0}^{k- 1}\begin{pmatrix}k - 1\\i\end{pmatrix}(-1)^{i} = [k = 1] \]

实际应用一般结合期望,也就是如果一个集合的期望最小不好求,可以去求他的期望最大。

高维前缀和

二维前缀和:

for(int i = 1; i <= n; ++ i) {for(int j = 1; j <= n; ++ j) {a[i][j] += a[i - 1][j];}
}
for(int i = 1; i <= n; ++ i) {for(int j = 1; j <= n; ++ j) {a[i][j] += a[i][j - 1];}
}

三维前缀和:

for(int i = 1; i <= n; ++ i) {for(int j = 1; j <= n; ++ j) {for(int k = 1; k <= n; ++ k) {a[i][j][k] += a[i - 1][j][k];}}
}
for(int i = 1; i <= n; ++ i) {for(int j = 1; j <= n; ++ j) {for(int k = 1; k <= n; ++ k) {a[i][j][k] += a[i][j - 1][k];}}
}
for(int i = 1; i <= n; ++ i) {for(int j = 1; j <= n; ++ j) {for(int k = 1; k <= n; ++ k) {a[i][j][k] += a[i][j][k - 1];}}
}

子集和:

用偏序的形式表示子集和,可以发现他就是一个 \(n\) 维,每个维度只有 01 的前缀和。

\[\sum_{T \subseteq S} a_T = \sum_{T_1 \le S_1\land T_1 \le S_1\land\cdots T_n \le S_n} a_T \]

for(int i = 0; i < n; ++ i) {	// 枚举维度,1011 用数组表示为 a[1][1][0][1]for(int s = 0; s < 1 << n; ++ s) {if(s >> i & 1) a[s] += a[s ^ 1 << i];}
}

子集和还有分治做法。

对于一个 \([0, 2^n)\) 的序列,每次把他分成两部分 \([0, 2^{n - 1})[2^{n - 1}, 2^n)\)

递归处理每个数在各自分治区间的子集和。

考虑合并两部分信息。

右边部分的第 \(n - 1\) 位都是 \(1\),左边部分的第 \(n - 1\) 位都是 \(0\),对应位呈现包含关系(\(x\) 对应 \(x + 2^{n - 1}\))。

因此右边再加上左半边对应的贡献就可求得当前分治区间的子集和。

时间复杂度 \(T(2^n) = 2T(2^{n - 1}) + O(2^n) = O(n2^n)\)

快速莫比乌斯变换

集合幂级数 \(F(x)\) 的莫比乌斯变换 \(\hat{F}(x)\) 满足:

\[[x^S]\hat{F}(x) = \sum_{T \subseteq S} [x^T] F(x) \]

莫比乌斯变换即高维前缀和。

莫比乌斯逆变换即高维差分,都可以按维 dp 做到 \(O(\vert U\vert2^{\vert U\vert})\)

集合并卷积(或卷积)

求集合幂级数 \(H(x) = F(x)G(x)\),满足

\[[x^S]H(x) = \sum_{T \cup R = S}[x^T]F(x)[x^R]G(x) \]

先求出 \(\hat{H}(x)\),再做逆变换。

\[\begin{aligned} \left[x^S\right]\hat H(s) &= \sum_{T\cup R \subseteq S}[x^T]F(x)[x^R]G(x)\\ \\ &= \sum_{T\subseteq S}[x^T]F(x)\sum_{R\subseteq S}[x^R]G(x)\\ \\ &= [x^S]\hat F(x)[x^S]\hat G(x) \end{aligned} \]

推广:集合交卷积(与卷积)

同样令 \(\hat H(x)\) 表示 \(H\) 的变换:

\[\begin{aligned} \left[x^S\right]\hat H(s) &= \sum_{S\subseteq T\cap R }[x^T]F(x)[x^R]G(x)\\ \\ &= \sum_{S\subseteq T}[x^T]F(x)\sum_{S\subseteq T}[x^R]G(x)\\ \\ &= [x^S]\hat F(x)[x^S]\hat G(x) \end{aligned} \]

类似的,只不过是高维前缀和换成高维后缀和。

集合无交并卷积(子集卷积)

\[[x^S]H(x) = \sum_{T \cup R = S,\ T\cap R = \varnothing}[x^T]F(x)[x^R]G(x) \]

考虑在集合幂级数中引入未定元 \(y\),指数代表集合大小。

\(x\) 做集合并卷积,\(y\) 做乘法卷积,求得 \(H^\prime(x, y) = F^\prime(x, y) G^\prime(x, y)\),其中 \([x^Sy^{\vert S\vert}]F^\prime(x, y) = [x^S]F(x)\)

两个集合无交当且仅当 \(\vert S\cup T\vert = \vert S\vert + \vert T\vert\)

因此有 \([x^S]H(x) = [x^Sy^{\vert S\vert}]H^\prime(x, y)\)

我们把形式幂集数 \(F^\prime(x, y)\) 看作一个 \(\vert U\vert\)\(2^{\vert U\vert}\) 的二维矩阵。

每一行保留大小为 \(i\) 的集合系数,其余全为 \(0\)

\(\vert U\vert^2\) 枚举 \(F^\prime\)\(G^\prime\) 的行,然后做两行的集合并卷积,时间复杂度 \(\vert U\vert^32^{\vert U\vert}\)

考虑 \(\vert U\vert^22^{\vert U\vert}\) 预处理出每一行的莫比乌斯变换,暴力算 \(y\) 卷积时只要 \(O(\vert U\vert)\) 对应系数相乘。

莫比乌斯变换是线性变换,不需要每做一次卷积就要逆变换,系数可以累加。

最后对每一行做莫比乌斯逆变换,时间复杂度 \(O(\vert U\vert^22^{\vert U\vert})\)

快速沃尔什变换

\[[x^S]\hat{H}(x) = \sum_{T\subseteq U}(-1)^{\vert S\cap T\vert} [x^T]F(x) \]

  • 注意 \(T\) 的范围是所有集合。

考虑分治。

对于 \([0, 2^n)\) 的区间,划分为 \([0, 2^{n - 1})[2^{n - 1}, 2^n)\) 两个子问题。

\(x\) 原来的系数为 \(f(x)\),考虑跨块贡献后的新系数为 \(f^\prime(x)\)

对于一个右侧元素 \(x + 2^{n + 1}\),左侧对他的贡献怎么算?

发现左侧对 \(x + 2^{n + 1}\) 的贡献和原来对 \(x\) 的贡献(即 \(f(x)\))是一样的,因为左边第 \(n - 1\) 位都为 \(0\)

右侧元素对 \(x + 2^{n + 1}\) 是否还是 \(f(x + 2^{n + 1})\)

\([2^{n - 1}, 2^n)\) 里做 FWT 时没有考虑第 \(n - 1\) 位的贡献,因此 \(f^{\prime}(x + 2^{n - 1}) = f(x) - f(x + 2^{n - 1})\)

类似地考虑左半边,\(f^{\prime}(x) = f(x) + f(x + 2^{n - 1})\)

沃尔什逆变换

试着对 \(\hat F(x)\) 再做一遍沃尔什变换。

\[\begin{aligned} \left[x^S\right]\hat{\hat F}(x)&= \sum_{T \subseteq U} (-1)^{\vert S\cap T\vert}\sum_{R\subseteq U}(-1)^{\vert T \cap R\vert}[x^R]F(x)\\ \\ &= \sum_{R\subseteq U}[x^R]F(x)\sum_{T \subseteq U} (-1)^{\vert (S\oplus R) \cap T\vert}\\ \\ &= \sum_{R\subseteq U}[x^R]F(x)\sum_{T \subseteq U} (-1)^{\vert (S\oplus R) \cap T\vert}\\ \\ &= \sum_{R\subseteq U}[x^R]F(x) \sum_{i = 0}^{\vert S\oplus R\vert}\begin{pmatrix}\vert S\oplus R\vert\\ i\end{pmatrix} 2^{\vert U\setminus S\oplus R\vert}\\ \\ &= \sum_{R\subseteq U}[x^R]F(x) 2^{\vert U\vert}[S = R] = 2^U[x^S]F(x) \end{aligned} \]

第二步中 \(\oplus\) 表示对称差。\(S\)\(R\) 的公共元素会对 \(-1\) 产生偶数次贡献。

我们发现只要将 \(\hat{\hat F}(x)\) 的各项系数乘上 \(\dfrac{1}{2^{\vert U\vert}}\) 即可还原 \(F(x)\),即沃尔什逆变换。

集合对称差卷积(异或卷积)

\(H(x) = F(x)G(x)\)

\[\begin{aligned} \left[x^S\right]\hat H(x)&= \sum_{T \subseteq S}(-1)^{\vert S\cup T\vert} [x^T]H(x)\\ \\ &= \sum_{T \subseteq S}(-1)^{\vert S\cup T\vert} \sum_{L\oplus R = T}[x^L]F(x)[x^R]G(x) \\ \\ &= \sum_{L, R}(-1)^{\vert S\cup (L\oplus R)\vert}[x^L]F(x)[x^R]G(x) \\ \\ &= \sum_{L}(-1)^{\vert S\cup L\vert}[x^L]F(x)\sum_{R}(-1)^{\vert S\cup R\vert}[x^R]G(x)\\ \\ &= [x^S]\hat F(x)[x^S]\hat G(x) \end{aligned} \]

burnside 引理

对于一个群 \((G, \times)\),里面的元素都是作用于集合 \(X\) 的置换。

\(h = f \times g\implies \forall x \in X,\ h(x) = g(f(x))\)

\((G, \times)\) 是群需要满足:

  1. \(\forall a, b \in G,\ a \times b \in G\)
  2. \(\forall a, b, c \in G,\ (a\times b) \times c = a\times (b \times c)\)
  3. \(\exists e \in G,\ \forall a \in G,\ e \times a = a \times e = a\)
  4. \(\forall a \in G,\exists b \in G,\ a \times b = e\),把 \(b\) 称作 \(a\) 的逆元。

如果 \(X\) 中两个元素可以通过 \(G\) 中置换变得相等,那么称他们等价,同属一个等价类。

\(X\) 中的等价类个数等于

\[\dfrac{1}{\vert G\vert} \sum_{g \in G} \sum_{x \in X} [g(x) = x] \]

拉格朗日插值

假设已知多项式 \(f(x)\)\(n\) 处点值 \((x_i, y_i)\),可以构造出满足这些点值限制的多项式:

\[g(x) = \sum_{i = 1}^n y_i \prod_{j \ne i} \dfrac{x - x_j}{x_i - x_j} \]

如果 \(f(x)\) 次数小于 \(n\),根据代数基本定理可知 \(f(x) = g(x)\)(我不会证)。

这意味着我们只需 \(n\) 个点值就能确定 \(f(x)\)

点值表示做乘法时只有 \(O(n)\) 而非卷积的 \(O(n^2)\)

通过点值还原 \(f(x)\) 可以先 \(O(n^2)\) 求出 \(\prod {x - x_j}\),然后对于求和的每一项 \(O(n)\) 除一个一次多项式即可。

CF722E Research Rover

题意:\(n \times m\) 的网格,图上 \(k\) 个关键点。给定初始权值 \(s\),每经过一个关键点权值减半(上取整)。

每次只能向右或向下走,求从 \((1, 1)\) 走到 \((n, m)\) 的期望权值。

将关键点排序。

最终权值只与经过的关键点数有关, \(f_{i, j}\) 表示走到第 \(i\) 个关键点恰好选了 \(j\) 个的方案数。

不怎么好转移,定义 \(g_{i, j}\) 表示走到 \(i\) 个关键点至少走了 \(j\) 个的方案数。

\[\begin{aligned} g_{i, j} &= \sum_{l = 0}^{i - 1}g_{l, j - 1} \begin{pmatrix}x_i - x_l + y_i - y_l\\ x_i - x_l\end{pmatrix} \\ \\ f_{i, j} &= g_{i, j} - g_{i, j + 1} \end{aligned} \]

由于我们将方案根据恰好经过的第 \(j - 1\) 个关键点进行分类,因此求得的 \(g\) 是不重不漏的。

\(j > 20\) 时权值一定削减为 \(1\),因此只需算到 \(j = 20\),剩下的贡献用总方案减掉即可。

submission

CF1097G Vladislav and a Great Legend

题意:给定一颗 \(n\) 个节点的树 \(T\),对应任意非空顶点集 \(X\)\(f(X)\) 定义为它在原图的极小连通子图中的边数,求:

\[\sum_{\varnothing \ne X \subseteq \{1, 2,\cdots, n\}} f(X)^k \]

其中 \(n \le 10^5,\ k \le 200\),极小连通子图可认为是保留所有边的虚树。

\[\begin{aligned} \sum_{\varnothing \ne X \subseteq \{1, 2,\cdots, n\}} f(X)^k = \sum_{i = 0}^{k}\begin{Bmatrix}k\\i\end{Bmatrix}i! \sum_{X} \begin{pmatrix}f(X)\\i\end{pmatrix} \end{aligned} \]

\(\begin{pmatrix}f(X)\\i\end{pmatrix}\) 的组合意义是从 \(X\) 的虚树中选 \(i\) 条边的方案数。

枚举虚树根 \(x\) 统计贡献。现在加入一颗子树 \(v\)

肯定是 \(v\) 里的点集与已经访问过子树中的点集(红色)进行配对,考虑一对点集产生多少方案。

我们需要考虑 \(1\) 选不选,\(2\) 选不选,\(3\) 选不选。

虽然他们都不是红色子树中的边,但是与 \(v\) 中点集配对后都会被经过。

\(f_{x, i}\) 表示以 \(x\) 为根的子树内选中 \(i\) 条边的生成树个数(方案不一定合法)。

注意这里选中的边不一定是生成树内部边,也有可能是生成树的根到 \(x\) 之间的边。

现在考虑 \(v\) 子树中的一棵生成树。

生成树内部以及生成树的根到 \(v\) 之间的边都已经决策过了,只要决策 \((x, v)\) 选还是不选。

\[f_{x, i + j}^{\prime} \gets f_{x, i} \times (f_{v, j} + f_{v, j - 1}) \]

其中 \(f^\prime\) 表示加入 \(v\) 后的 \(f\) 值。

注意这一部分的答案是要计入最终贡献的,因为统计的都是合法方案。

假设 \(v\) 与右边结合的方案已经计算完了。

现在要把一些只在 \(v\) 子树的点集加入 \(f\),为下一棵子树的转移做准备。

点集的根到 \(v\) 都决策过了,还是考虑选不选 \((x, y)\)

\[f_{x, i}^{\prime} \gets f_{v, i} + f_{v, i - 1} \]

复杂度据说转移时对 \(k\) 和子树大小取 \(\min\) 就能做到 \(O(nk)\),很神秘。submission

CF1750G Doping

题意:疑似有点太难了。

CF1967E1 Again Counting Arrays (Easy Version)

题意:给定 \(n, m, b_0\),求长度为 \(n\) 的序列 \(a\) 个数,\(1 \le a_i \le m\) 且存在一个非负序列 \(b\) 满足 \(\forall i \in [1, n], a_i \ne b_i\land\vert b_i - b_{i - 1} \vert = 1\)

\(n, m, b_0 \le 2\times 10^5\)

由于要保证 \(b_i\) 非负,贪心的使 \(b_i\) 尽可能大:

  • \(b_{i - 1} + 1 \ne a_i \to b_i = b_{i - 1} + 1\)
  • \(b_{i - 1} + 1 = a_i \to b_i = b_{i - 1} - 1\)

如果其中出现 \(b_i\) 为负,则序列 \(a\) 并不存在一个合法的 \(b\)

显然每个 \(a\) 可以按照这种方式唯一生成一个 \(b\),考虑对 \(b\) 计数。

\(f_{i, j}\) 表示满足 \(b_i = j\) 的序列 \(a\) 个数。

第一种转移 \((m - 1)f_{i, j} \to f_{i + 1, j + 1}\)。第二种转移 \([j < m]f_{i, j} \to f_{i + 1, j - 1}\)

如果第 \(i\) 个数已经到 \(m\) 了,后面随便怎么填都合法,不妨就用 \(f_{i, m}\) 记录 \(j \ge m\) 的所有情况:\(mf_{i, m} \to f_{i + 1, m}\)

时间复杂度 \(O(nm)\),不能通过。

从另一个角度考虑这个问题,把 \(b\) 的生成看作一个点从 \((0, b_0)\) 开始的游走,碰到 \(y = m\)\(x = n\) 则结束游走。

如果第 \(i\) 步往右上走,说明 \(a_i\)\(m - 1\) 种取值;否则 \(a_i\) 只有一种取值。

枚举 \(O(n)\) 种终点 \((i, m)\)\((n, j)\),求从 \((0, b_0)\) 不经过 \(y = -1\)\(y = m\) 到达终点的路径数。

终点确定向右上和右下的步数也确定,往右上走对应 \(m - 1\)\(a\) 的取值,往右下走对应唯一一种取值。

由于最后一步是确定的,反射容斥的终点设为 \((i - 1, m - 1)\) 可以规避一些边界。反射容斥做到单次 \(O(\dfrac{n}{m})\)

取阈值 \(B = \sqrt n\),按照 \(m\) 的大小分两种做法,时间复杂度 \(O(nB + \dfrac{n^2}{B})\)。submission

P4221 [WC2018] 州区划分

题意:\(n\) 个城市划分为若干州。一个州合法当且仅当其生成子图不存在欧拉回路。求所有合法划分的满意度之和。

一个划分的满意度等于所有州的满意度之积。

\(i\) 个州的满意度定义为第 \(i\) 个州的人口在前 \(i\) 个州的人口中所占比例的 \(p\) 次幂,即

\[\bigg(\dfrac{\sum_{x \in S_i}w_x}{\sum_{j = 1}^i \sum_{x \in S_j} w_x}\bigg)^p \]

给出每个城市的人口 \(w_i\) 以及常数 \(p\),保证 \(n \le 21\) 且无重边无自环。

\(O(m2^n)\) 预处理每个州 \(S\) 是否合法,\(S\) 中存在欧拉回路当且仅当子图连通且所有点度数为偶。

\(W(S) = (\sum_{x \in S} w_x)^p\)\(f(S)\) 表示全集为 \(S\) 时的答案。

枚举 \(S\) 中最后一个州 \(T\)

\[f(S) = \sum_{T \subseteq S} \text{legal}(T)\times f(S \setminus T) \times \dfrac{W(T)}{W(S)} \]

\(W(S)\) 提出来,记 \(g(T) = \text{legal}(T) \times {W(T)}\),中间的 \(f(S\setminus T) \times g(T)\) 实际就是一个子集卷积(集合无交并)。

\([x^Sy^{\vert S\vert}]g^{\prime}(x, y) = [x^S]g(x)\)\(x\) 做或卷积,\(y\) 做乘法卷积。

把幂级数看作 \(n \times 2^n\) 的矩阵,每次枚举 \(f^{\prime}\) 的行 \(i\),和 \(g\) 的每行(除第 \(0\) 行)做或卷积,把答案累计到 \(j > i\)\(f^{\prime}\) 上(乘法卷积使 \(y\) 的指数变大)。

时间复杂度 \(O(n^22^n)\)。submission

NFLSOJ 3392. 计算

题意:定义 \(F(x, a, b) = \gcd(x^a - 1, x^b - 1) + 1\),如果 \(a, b\) 其一为零则值为零。

给出 \(m, a, b, c, d\),令 \(L = F(m, a, b) + 1, R = F(m, c, d)\),保证 \(L < R \le 10^{18}, m \le 10^7\)

求集合 \(\{L, L + 1, \cdots, R - 1, R\}\) 有多少个子集和能被 \(m\) 整除。

观察 \(F\) 的定义,把他放在 \(x\) 进制下考虑,不难发现 \(F(x, a, b) = x^{\gcd(a, b)}\),举个十进制的例子:\(\gcd(9999, 99) = \gcd(9999 - 9900, 99) = 10^{\gcd(4, 2)} - 1\)

由于 \(L \equiv 1 \pmod m\)\(R \equiv 0\pmod m\),因此每种余数出现的次数都是 \(n = \dfrac{R - L + 1}{m}\)

枚举子集和:

\[\begin{aligned} \sum_{i = 0}^{+\infty}[m \mid i] [x^i]\prod_{j = 0}^{m - 1}(1 + x^j)^n&= \sum_{i = 0}^{+\infty}\dfrac{1}{m}\sum_{t = 0}^{m - 1} w_m^{ti} [x^i]\prod_{j = 0}^{m - 1}(1 + x^j)^n\\ \\ &= \dfrac{1}{m}\sum_{t = 0}^{m - 1} \sum_{i = 0}^{+\infty}[x^i]\prod_{j = 0}^{m - 1}\big(1 + (w_m^tx)^j\big)^n\\ \\ &= \dfrac{1}{m}\sum_{t = 0}^{m - 1} \prod_{j = 0}^{m - 1}\big(1 + w_m^{tj}\big)^n\\\end{aligned} \]

考虑如果 \(w_m^{ti} = w_m^{tj}\) 也就是 \(ti \equiv tj \pmod m\)

那么有 \(m \mid t(i - j)\),因此指数循环的最小正周期为 \(m/d\),且 \(0, d, 2d, \cdots, (m/d - 1)d\) 每个恰好出现一次,\(d = \gcd(t, m)\)

(最小正周期内两两不同余是显然的,\(tj \equiv x \pmod m\) 的必要条件是 \(d \mid x\)

因此:

\[\prod_{j = 0}^{m - 1}\big(1 + w_m^{tj}\big)^n = \prod_{j = 0}^{m/d - 1}\big(1 + w_{m / d}^{j}\big)^{nd} \]

说明这个乘积与 \(t\) 无关,不妨直接枚举 \(d\)

\[\dfrac{1}{m}\sum_{d \mid m} \sum_{t = 1}^m[t \perp \frac{m}{d}]\prod_{j = 0}^{m/d - 1}\big(1 + w_{m / d}^{j}\big)^{nd} = \dfrac{1}{m}\sum_{d \mid m} \varphi(\frac{m}{d})\prod_{j = 0}^{m/d - 1}\big(1 + w_{m / d}^{j}\big)^{nd} \]

根据分圆多项式 \(x^m - 1 = \prod_{i = 0}^{m - 1} (x - w_{m}^i)\)

\[\begin{aligned} \dfrac{1}{m}\sum_{d \mid m} \varphi(\frac{m}{d})(-1)^{nd}\prod_{j = 0}^{m/d - 1}\big(-1 - w_{m / d}^{j}\big)^{nd} &= \dfrac{1}{m}\sum_{d \mid m} \varphi(\frac{m}{d})(1 -(-1)^{\frac{m}{d}})^{nd}\\ \\ &= \dfrac{1}{m}\sum_{d \mid m}[2\nmid d] \varphi(d)2^{nm/d}\\ \end{aligned} \]

暴力枚举因子,时间复杂度 \(O(\sqrt m + d(m)\log n)\)。submission

NFLSOJ 5005. 礼物

题意:计算有多少个不同的有 \(n\) 个珠子的手环,满足有 \(m\) 个珠子是金色的,且金色珠子的最长连续段长度不超过 \(k\)

两个手环相同当且仅当它们可以通过旋转变得一模一样。\(1 \le n \le 10^6 , 0 \le k \le m \le n\)

一共 \(n\) 种旋转置换,第 \(i\) 个表示顺时针转 \(i\) 格,计算每种置换对应的不动点个数,最后除以 \(n\)

考虑一种染色方案的最小正周期 \(T \mid n\),不妨破环成无限长的链,\(f(p) = f(p + T)\)

如果存在 \(i\) 使得 \(f(p) = f(p + i)\),一定有 \(T \mid i\),即所有 \(T \mid \gcd(i, n)\) 的方案会被 \(i\) 计算到。

考虑枚举 \(d = \gcd(i, n)\) 作为周期,使每种最小正周期 \(T\mid d\) 被恰好算一次,有 \(\varphi(\frac{n}{d})\) 种置换满足 \(d = \gcd(i, n)\)

假设已经特判掉 \(d = n\) 的情况,现在可以把环拆成 \(\frac{n}{d}\) 个完全相同的部分(已经变成链了),对这部分计数。

\(n \gets d, m \gets \frac{md}{n}\)。不妨把 \(n - m\) 个白子先排列好,然后插空,满足任意间隔不插超过 \(k\) 个。

最右边的间隔不能填,因为和下一循环节的最左间隔等闲。那么问题转化为求不定方程 \(\sum_{i = 1}^{n - m} x_i = m,\ 0 \le x \le k\) 的解的数量。

钦定 \(z\) 个超过 \(k\),总和可以减掉 \((k + 1)z\),等价于 \(\sum_{i = 1}^{n - m} x_i = m - kz\) 的非负整数解数 \(\begin{pmatrix}n - (k + 1)z - 1\\ n - m - 1\end{pmatrix}\),因此可以 \(O(d)\) 容斥。

时间复杂度 \(\sum_{d \mid n} d = \sigma(n)\),即 \(O(n\log\log n)\)。submission

NFLSOJ 12341. 异或

PKUSC 2023 Day1 狼人杀

P10221 [省选联考 2024] 重塑时光

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/55221.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

WPF 从裸 Win 32 的 WM_Pointer 消息获取触摸点绘制笔迹

本文将告诉大家如何在 WPF 里面,接收裸 Win 32 的 WM_Pointer 消息,从消息里面获取触摸点信息,使用触摸点信息绘制简单的笔迹开始之前必须说明的是使用本文的方法不会带来什么优势,既不能带来笔迹书写上的加速,也不能带来笔迹效果的平滑,且代码复杂。本文唯一的作用只是让…

WPF 开启Pointer消息存在的坑

本文记录在 WPF 开启 Pointer 消息的坑屏幕键盘 启用了Pointer之后,调用 TextBox.Focus() 方法时,有一定的可能起不来屏幕键盘,必须点在控件之上才行,触摸在它之上才行 后续的 Win10 版本似乎修复了这个问题,暂时还没了解到具体是从哪个版本开始修复 使用屏幕绝对坐标而不…

MIUI系统,APKMirror Installer安装apkm的时候提示app installation failed Installation aborted解决方案

场景 我的手机是MIUI系统,通过APKMirror Installer安装apkm的时候提示app installation failed Installation aborted。 本来不想装了,心想可能是版本的兼容问题,但是我查看的SDK的版本和我的android是匹配的,不应该会失败,那是为什么呢? 解决方案 禁用掉开发者选项中的启…

Serilog文档翻译系列(三) - 基础配置

Serilog基础配置:创建日志记录器、接收器、输出模板、最低级别、覆盖每个接收器、增强器、过滤器、子日志记录器 Serilog 使用简单的 C# API 来配置日志记录。当需要外部配置时,可以(慎用)通过使用 Serilog.Settings.AppSettings 包或 Serilog.Settings.Configuration 包进…

全网最适合入门的面向对象编程教程:42 Python常用复合数据类型-collections容器数据类型

在Python中,collections模块提供了一组高效、功能强大的容器数据类型,扩展了内置的基础数据类型(如list、tuple、dict等),这些容器数据类型在处理特定问题时,能够提供更简洁、更高效的解决方案。全网最适合入门的面向对象编程教程:42 Python 常用复合数据类型-collectio…

MIT6.S081(2023 Fall) Lab2 Lab3 总结

Lab1 可以说就是一些编程相关的工作,只是程序中有一些操作系统相关的概念(例如进程、管道)。做完Lab1之后我有一个问题:系统调用时如何进行的,为什么我在user下调用sleep( ),就可以直接调用到内核中的sleep代码,我并没有看到两者是如何联系的。做完Lab2,这个问题得到了…

稍微改一下 Wiki.js 的界面 CSS

Wiki.js 默认样式那个样子真的太丑了,又黑又蓝。。。反正我自己不太中意就写了覆盖样式换了 换了纯白的风格,用在自己的站了,样子见下:相关链接仓库:https://github.com/AurLemon/wikijs-citizen-styles 下载:https://github.com/AurLemon/wikijs-citizen-styles/release…

第四天---RSA进阶题型

T1.小明文攻击 一.题目: from Crypto.Util.number import * from gmpy2 import *flag = bNSSCTF{******}p = getPrime(5120) q = getPrime(5120)n = p*q e = 97 phi = (p-1)*(q-1)m = bytes_to_long(flag) c = powmod(m, e, n)print(fn = {n}) print(fe = {e}) print(fc = {c}…