2025 春季数论

上升幂

上升阶乘幂 xn=k=0n1(x+k)\displaystyle x^{\overline{n}}=\prod_{k=0}^{n-1} (x+k)

下降幂

下降阶乘幂 xn=k=0n1(xk)\displaystyle x^{\underline{n}}=\prod_{k=0}^{n-1} (x-k)

斯特林函数

一类

定义

第一类斯特林数(斯特林轮换数)(斯大林数) [nk]\begin{bmatrix}n\\ k\end{bmatrix},也(不知道可不)可记做 S1(n,k)S^1(n,k),表示将 nn 个两两不同的元素,划分为 kk 个互不区分的非空圆排列(轮换)的方案数。

递推式

[nk]=[n1k1]+(n1)[n1k]\begin{bmatrix}n\\ k\end{bmatrix}=\begin{bmatrix}n-1\\ k-1\end{bmatrix}+(n-1)\begin{bmatrix}n-1\\ k\end{bmatrix}

边界是 [n0]=[n=0]\begin{bmatrix}n\\ 0\end{bmatrix}=[n=0]

证明显然,读者自证不难。

上升幂转普通幂:

xn=k[nk]xkx^{\overline{n}}=\sum_{k} \begin{bmatrix}n\\ k\end{bmatrix} x^k

下降幂转普通幂:

xn=k[nk](1)nkxkx^{\underline{n}}=\sum_{k} \begin{bmatrix}n\\ k\end{bmatrix} (-1)^{n-k} x^k

二类

第二类斯特林数(斯特林子集数)(斯二林数) {nk}\begin{Bmatrix}n\\ k\end{Bmatrix},也(不知道可不)可记做 S2(n,k)S^2(n,k),表示将 nn 个两两不同的元素,划分为 kk 个互不区分的非空子集的方案数。

递推式

{nk}={n1k1}+k{n1k}\begin{Bmatrix}n\\ k\end{Bmatrix}=\begin{Bmatrix}n-1\\ k-1\end{Bmatrix}+k\begin{Bmatrix}n-1\\ k\end{Bmatrix}

边界是 {n0}=[n=0]\begin{Bmatrix}n\\ 0\end{Bmatrix}=[n=0]

证明显然。

普通幂转上升幂:

xn=k{nk}(1)nkxkx^n=\sum_{k} \begin{Bmatrix}n\\ k\end{Bmatrix} (-1)^{n-k} x^{\overline{k}}

普通幂转下降幂:

xn=k{nk}xkx^n=\sum_{k} \begin{Bmatrix}n\\ k\end{Bmatrix} x^{\underline{k}}

斯特林反演

定义

f(n)=k=0n{nk}g(k)    g(n)=k=0n(1)nk[nk]f(k)f(n)=\sum_{k=0}^{n}\begin{Bmatrix}n\\ k\end{Bmatrix}g(k)\iff g(n)=\sum_{k=0}^{n} (−1)^{n−k}\begin{bmatrix}n\\ k\end{bmatrix}f(k)

二项式反演

定义

g(n)=i=0n(ni)f(i)    f(n)=i=0n(ni)(1)nig(i)g(n)=\sum_{i=0}^{n}\dbinom{n}{i}f(i) \\ \iff \\ f(n)=\sum_{i=0}^{n}\dbinom{n}{i}(-1)^{n-i}g(i)

多项式卷积

FFT

给定一个 nn 次多项式 F(x)F(x),和一个 mm 次多项式 G(x)G(x)

请求出 F(x)F(x)G(x)G(x) 的卷积。

1n,m1061 \le n, m \leq {10}^6

思考以下构造,对于一个 n1n-1 次多项式 F(x)=i=0n1aixi\displaystyle F(x)=\sum_{i=0}^{n-1}a_ix^i,我们只需要找到 nn 个互不相同的点 (xi,yi)(x_i,y_i),那么就可以唯一确定地构造出这个函数。

而两个函数的卷积,假设结果为 H(i)H(i),那么就一定可以找出 n+m+1n+m+1 个点来构造出它,这些点是 (xi,F(xi)×G(xi))(x_i,F(x_i)\times G(x_i)),所以我们现在需要一个算法快速找出 n+m+1n+m+1 个函数的点值。

FFT(快速傅里叶变换),可以在 Θ(nlogn)\Theta(n\log n) 的时间复杂度内求解。

思路:我们可以不局限于实数域内,把目光放到复数域内,考虑将单位根带入 F,GF,G

FFT 算法的基本思想是分治。它分治地来求当 x=ωnkx=\omega_n^k 的时候 F(x)F(x) 的值。FFT 的分治思想体现在将多项式分为奇次项和偶次项处理。

举个例子,对于一共 88 项的多项式:

F(x)=a0+a1x+a2x2+a3x3+a4x4+a5x5+a6x6+a7x7F(x)=a_0+a_1x+a_2x^2+a_3x^3+a_4x^4+a_5x^5+a_6x^6+a_7x^7

按照次数的奇偶来分成两组,然后右边提出来一个 xx

F(x)=(a0+a2x2+a4x4+a6x6)+(a1x+a3x3+a5x5+a7x7)=(a0+a2x2+a4x4+a6x6)+x(a1+a3x2+a5x4+a7x6)\begin{aligned} F(x) &= (a_0+a_2x^2+a_4x^4+a_6x^6) + (a_1x+a_3x^3+a_5x^5+a_7x^7)\\ &= (a_0+a_2x^2+a_4x^4+a_6x^6) + x(a_1+a_3x^2+a_5x^4+a_7x^6) \end{aligned}

分别用奇偶次次项数建立新的函数:

G(x)=a0+a2x+a4x2+a6x3H(x)=a1+a3x+a5x2+a7x3\begin{aligned} G(x) &= a_0+a_2x+a_4x^2+a_6x^3\\ H(x) &= a_1+a_3x+a_5x^2+a_7x^3 \end{aligned}

那么原来的 F(x)F(x) 用新函数表示为:

F(x)=G(x2)+x×H(x2)F(x)=G\left(x^2\right) + x \times H\left(x^2\right)

利用偶数次单位根的性质 ωni=ωni+n/2\omega^i_n = -\omega^{i + n/2}_n,和 G(x2)G\left(x^2\right)H(x2)H\left(x^2\right) 是偶函数,我们知道在复平面上 ωni\omega^i_nωni+n/2\omega^{i+n/2}_nG(x2)G(x^2)H(x2)H(x^2) 对应的值相同。得到:

F(ωnk)=G((ωnk)2)+ωnk×H((ωnk)2)=G(ωn2k)+ωnk×H(ωn2k)=G(ωn/2k)+ωnk×H(ωn/2k)\begin{aligned} F(\omega_n^k) &= G((\omega_n^k)^2) + \omega_n^k \times H((\omega_n^k)^2) \\ &= G(\omega_n^{2k}) + \omega_n^k \times H(\omega_n^{2k}) \\ &= G(\omega_{n/2}^k) + \omega_n^k \times H(\omega_{n/2}^k) \end{aligned}

和:

F(ωnk+n/2)=G(ωn2k+n)+ωnk+n/2×H(ωn2k+n)=G(ωn2k)ωnk×H(ωn2k)=G(ωn/2k)ωnk×H(ωn/2k)\begin{aligned} F(\omega_n^{k+n/2}) &= G(\omega_n^{2k+n}) + \omega_n^{k+n/2} \times H(\omega_n^{2k+n}) \\ &= G(\omega_n^{2k}) - \omega_n^k \times H(\omega_n^{2k}) \\ &= G(\omega_{n/2}^k) - \omega_n^k \times H(\omega_{n/2}^k) \end{aligned}

因此我们求出了 G(ωn/2k)G(\omega_{n/2}^k)H(ωn/2k)H(\omega_{n/2}^k) 后,就可以同时求出 F(ωnk)F(\omega_n^k)F(ωnk+n/2)F(\omega_n^{k+n/2})。于是对 GGHH 分别递归即可。

NTT

和 FFT 没什么区别。FFT 很大的问题是没法取模(因为用了大量复数和浮点数),NTT 解决了这个问题。

NTT 试图在整数域内寻找这样的根,实际上在同余意义下确实有这样的数,它就是原根。

原根是什么?简单来说,就是多次次方以后可以覆盖完整个简化剩余系的数。

举个例子。

301(mod7)313(mod7)322(mod7)336(mod7)344(mod7)355(mod7)361(mod7)\begin{aligned} 3^0 \equiv 1 \pmod 7\\ 3^1 \equiv 3 \pmod 7\\ 3^2 \equiv 2 \pmod 7\\ 3^3 \equiv 6 \pmod 7\\ 3^4 \equiv 4 \pmod 7\\ 3^5 \equiv 5 \pmod 7\\ 3^6 \equiv 1 \pmod 7\\ \cdots\cdots\cdots\cdots\cdots\cdots \end{aligned}

所以 33 就是 77 的一个原根。

显然,它具有单位根的种种性质,使得它可以在模意义下代替单位根。

Polya 定理与 Burnside 引理

Burnside 引理

定义

Burnside 引理主要用于计算群作用下的轨道数目。假设存在一个有限群 GG 作用于集合 XX,那么不同等价类的数量可以通过以下公式计算:

N=1GgGFix(g)N = \frac{1}{|G|} \sum_{g \in G} \mathrm{Fix}(g)

这里的 Fix(g)\mathrm{Fix}(g) 指的是集合 XX 中在置换 gg 作用下保持不变的元素(也就是不动点)的个数。

证明

对于集合 XX 中的任意元素 xx,其等价类的大小为 G.x=GStab(x)|G.x| = \frac{|G|}{|\text{Stab}(x)|}。其中,Stab(x)={gGg(x)=x}\text{Stab}(x) = \{g \in G \mid g(x) = x\} 表示元素 xx 的不动点集合。

我们来统计所有满足 g(x)=xg(x) = x(g,x)(g, x) 对。可以得到:

gGFix(g)=xXStab(x).\sum_{g \in G} \mathrm{Fix}(g) = \sum_{x \in X} |\text{Stab}(x)|.

接着,我们将集合 XX 按照轨道进行分解,可表示为 X=i=1NOiX = \bigcup_{i=1}^N O_i。那么就有:

xXStab(x)=i=1NxOiStab(x).\sum_{x \in X} |\text{Stab}(x)| = \sum_{i=1}^N \sum_{x \in O_i} |\text{Stab}(x)|.

对于每一个轨道 OiO_i,根据轨道 - 稳定化子定理可知:

xOiStab(x)=G.\sum_{x \in O_i} |\text{Stab}(x)| = |G|.

所有轨道的贡献总和为 NGN \cdot |G|,将其代入前面双重计数的结果中,就可以得到:

gGFix(g)=NG    N=1GgGFix(g).\sum_{g \in G} \mathrm{Fix}(g) = N \cdot |G| \implies N = \frac{1}{|G|} \sum_{g \in G} \mathrm{Fix}(g).

Polya 定理

定义

Polya 定理实际上是 Burnside 引理在染色问题中的具体应用。设 GG 是作用在 nn 个对象上的置换群,使用 mm 种颜色对这些对象进行染色,那么不同的染色方案数可以通过以下公式计算:

1GgGmc(g)\frac{1}{|G|} \sum_{g \in G} m^{c(g)}

其中,c(g)c(g) 表示置换 gg 的循环节数,也就是将置换分解为不相交轮换的个数。

例如,对于正六边形的旋转群,其每个置换都对应着不同的旋转角度,我们只需计算出每个置换的循环数,然后代入上述公式即可。

证明

对于置换群 GG 中的每一个置换 gg,都可以将其分解为 c(g)c(g) 个不相交的轮换。例如,旋转 60° 对应的就是一个 6 - 轮换。需要注意的是,在轮换内的对象位置必须同步变动。

一个染色方案在置换 gg 作用下保持不变的充要条件是,每个轮换内的对象颜色都相同。

下面举例说明:若置换 gg 可以分解为 2 个轮换,且这两个轮换的长度均为 3,那么在染色时,第一个轮换内的所有对象颜色必须相同,第二个轮换内的所有对象颜色也必须相同。

由于每个轮换都有 mm 种颜色可供选择,所以总的不动点数为:

Fix(g)=mc(g).\mathrm{Fix}(g) = m^{c(g)}.

Fix(g)=mc(g)\mathrm{Fix}(g) = m^{c(g)} 代入 Burnside 公式,就能够得到:

N=1GgGmc(g).N = \frac{1}{|G|} \sum_{g \in G} m^{c(g)}.

线性基

前言

由于以及线性基的概念过于抽象,我无法完全理解, 所以我将针对某一道确切的题目来进行阐述。

定义

例如针对这道异或线性基的题来说吧。

我们假设一个数列 AA 中元素相互异或可以表示出来的值有另一个集合 BB 也可以表述出来,且 BB 满足一下性质。

  • 线性无关(即任意非空子集的异或和不为 00
  • AA 中的任意元素 xx,都可在 BB 中取出若干元素使其异或和为 xx
  • 对任意满足上两条的集合 BB',其元素个数不会小于 BB 的元素个数。

用途

  • 判断一个数能否表示成某数集子集的异或和;
  • 求一个数表示成某数集子集异或和的方案数;
  • 求某数集子集的最大/最小/第 kk 大/第 kk 小异或和;
  • 求一个数在某数集子集异或和中的排名。

构造

具体来说怎么构造呢?

容易发现,线性基内的每一个数的最高位 11 的位置是不重的(重了的就可以把它们俩异或一下),所以我们可以记录每一个最高位对应那个线性基元素。

具体来说,对原集合的每个数 kk 转为二进制,从高位向低位扫,对于第 ii 位是 11 的,如果 pip_i 不存在,那么令 pikp_i \leftarrow k 并结束扫描,如果存在,令 kk xor pik\leftarrow k~\text{xor}~p_i

或者使用高斯消元的方式来构建线性基,这样构建出来的线性基就是有一些很好的性质,于是我们考虑如何将贪心构造的线性基转化为高斯消元的线性基。

观察得到,我们显然可以对着最后的贪心得到的线性基进行一遍消元,然后就可以了。

那它有什么神奇的性质要我们这么做呢?比如我们可以对于某一个给定的 kk,对它进行二进制分位,可以发现如果第 ii 位为 11,那么就异或上 pip_i 最后得到的就是第 kk 小的异或值。

证明显然。

对着代码可能好理解一点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include<bits/stdc++.h>
using namespace std;
int n, a[50], d[50];
int main() {
cin.tie(0)->sync_with_stdio(false);
cin >> n;
for (int i = 1; i <= n; ++i) cin >> a[i];
for (int i = 1; i <= n; ++i) {
bitset<50> b;
b = a[i];
for (int j = 49; j >= 0; --j) {
if (b[j]) {
if (!d[j]) {
d[j] = a[i];
break;
}
b ^= d[j];
}
}
}
int ans = 0;
for (int i = 49; i >= 0; --i) {
if ((ans ^ d[i]) > ans) ans ^= d[i];
}
cout << ans << endl;
return 0;
}

至于基和线性基具体是什么,那么我们可能得扯一点数学的概念了。

在线性代数中,基(也称为基底)是描述、刻画向量空间的基本工具。向量空间的基是它的一个特殊的子集,基的元素称为基向量。向量空间中任意一个元素,都可以唯一地表示成基向量的线性组合。如果基中元素个数有限,就称向量空间为有限维向量空间,将元素的个数称作向量空间的维数。

向量空间 VV 的一组向量若满足

  1. 线性无关

  2. VV 中任一向量可由此向量线性表出

则称该组向量是 VV 中的一个基(亦称基底)。

一个向量空间的基有很多,但每个基所含向量个数却是个定数。

其实在我个人看来,向量空间和群有挺高的相似度的,而基就相当于剩余系中的简化剩余系(不恰当比喻+=2)

线性表出意味着什么呢,就是通过对基内向量的放缩,再进行加法,就可以表示线性空间内的所有量的话,它就是向量空间的一个基。

但是,我们并不需要搞那么复杂,OI 中有关线性基的应用一般只涉及两类线性空间:nn 维实数域线性空间 Rn\mathbf{R}^nnn 维布尔域线性空间 Z2n\mathbf{Z}_2^n


2025 春季数论
https://www.lzj-blog.top/2025/03/14/2025 春季数论/
作者
lzj
发布于
2025年3月14日
许可协议