数论杂记
数论杂记
数论函数
数论函数是指这样一类函数:其定义域是正整数,值域是一个数集。
定义两个数论函数的加法,为逐项相加,即 \((f + g)(n) = f(n) + g(n)\) 。
定义数乘这个数和每一项都相乘,即 \((xf)(n) = x \times f(n)\) 。
常见数论函数
常见数论函数的性质
证明:考虑每个因数的贡献即可。
证明:考虑把每个因子一一映射,如果 \(ij\) 的因子 \(k\) 中有一个因子 \(p^c\),\(i\) 中有因子 \(p^a\),\(j\) 中有因子 \(p^b\)。我们规定:
- 如果 \(c\leqslant a\),那么在 \(i\) 中选择。
- 如果 \(c>a\),那么我们把 \(c\) 减去 \(a\),在 \(j\) 中选择 \(p^{c-a}\)(在 \(j\) 中选择 \(p^e\) 表示的是 \(p^{a+e}\))
对于 \(ij\) 的因子 \(k\) 的其他因子同理。于是对于任何一个 \(k\) 有一个唯一的映射,且每一个选择对应着唯一的 \(k\)。
于是对于 \(ij\) 的因子 \(k=\prod {p_i}^{c_i}\),我们不可能同时在 \(i\) 和 \(j\) 中选择 \(p_i\)(优先在 \(i\) 中选择,如果不够就只在 \(j\) 中选择不够的指数),故 \(x\) 和 \(y\) 必须互质。
推广:
积性函数
定义
积性函数
对于函数 \(f(x)\) ,若 \(\forall \gcd(x, y) = 1, f(x y) = f(x) f(y)\) ,则称 \(f(x)\) 为积性函数。
常见的积性函数:
- 约数函数:\(\sigma_k(n) = \sum_{d | n} d^k\) 。
- 欧拉函数:\(\varphi(n)\) 。
- 莫比乌斯函数:\(\mu(n)\)
完全积性函数
对于函数 \(f(x)\) ,若 \(\forall x, y, f(x y) = f(x) f(y)\) ,则称 \(f(x)\) 为完全积性函数。不难发现完全积性函数属于积性函数。
常见的完全积性函数:
- 常数函数: \(1(n) = 1\) 。
- 元函数: \(\epsilon(n) = [n = 1]\) 。
- 单位函数:\(id(n) = n\) 。
- 幂函数: \(id^x(n) = n^x\) 。
性质
一个显然的事实:\(f(1) = 1\) 。
设 \(n\) 的质因数分解为 \(\prod p_i^{c_i}\) ,则:
- 对于积性函数 \(f(x)\) ,有 \(f(n) = \prod f(p_i^{c_i})\) 。
- 对于完全积性函数 \(f(x)\) ,有 \(f(n) = \prod f(p_i)^{k_i}\) 。
若 \(f(n), g(n)\) 均为积性函数,则以下函数也为积性函数:
线性筛
线性筛的时间复杂度是由每个数都会被最小的质因子标记的。
一般的,对于积性函数 \(f(x)\) ,若 \(f(p^c)\) 的值便于分析,则 \(f(1 \sim n)\) 的值可以被线性筛筛出来。
记 \(low_i\) 表示:若 \(i\) 的最小质因子为 \(p_1\) ,其次数为 \(c_1\) ,则 \(low_i = p_1^{c_1}\) 。
在线性筛时,若当前筛出了一个质数 \(p\) ,则将 \(f(p), f(p^2), \cdots, f(p^c)\) 都算出来,否则可以得到 \(f(i) = f(\dfrac{i}{low_i}) \times f(low_i)\) 。
inline void sieve(int n) {
f[1] = 1;
for (int i = 2; i <= n; ++i) {
if (!low[i]) {
pri[++pcnt] = i;
ll x = i;
int c = 1;
while (x <= n) {
low[x] = x;
// calculate f(x)
x *= i, c ++;
}
}
for (int j = 1; j <= pcnt && i * pri[j] <= n; ++j) {
int x = i * pri[j];
low[x] = i % pri[j] ? pri[j] : low[i] * pri[j];
f[x] = f[x / low[x]] * f[low[x]];
if (!(i % pri[j]))
break;
}
}
}
Dirichlet 卷积
定义:
-
Dirichlet 卷积:\(f(n), g(n)\) 的狄利克雷卷积为 \((f * g) (n) = \sum_{d | n} f(d) g(\dfrac{n}{d})\) 。
-
逆:满足 \(\epsilon = g * f\) 时,\(g, f\) 互逆,对于每个 \(f(1) \neq 0\) 的函数都存在逆元,可以构造:
\[g(n) = \dfrac{1}{f(1)} ([n = 1] - \sum_{i | n, i \neq 1} f(i) g(\dfrac{n}{i})) \]
性质:
- 交换律:\(f * g = g * f\) 。
- 结合律:\((f * g) * h = f * (g * h)\) 。
- 分配律:\((f + g) * h = f * h + g * h\) 。
- 数乘:\((xf) * g = x(f * g)\) 。
- 单位元:\(\epsilon * f = f\) 。
- 若 \(h(1) \neq 0\) ,则 \(f = g \iff f * h = g * h\) 。
- 积性函数的卷积、逆仍为积性函数。
常见 Dirichlet 卷积式:
线性筛
线性筛的时间复杂度是由每个数都会被最小的质因子标记的。
一般的,对于积性函数 \(f(x)\) ,若 \(f(p^c)\) 的值便于分析,则 \(f(1 \sim n)\) 的值可以被线性筛筛出来。
记 \(low_i\) 表示:若 \(i\) 的最小质因子为 \(p_1\) ,其次数为 \(c_1\) ,则 \(low_i = p_1^{c_1}\) 。
在线性筛时,若当前筛出了一个质数 \(p\) ,则将 \(f(p), f(p^2), \cdots, f(p^c)\) 都算出来,否则可以得到 \(f(i) = f(\dfrac{i}{low_i}) \times f(low_i)\) 。
筛素数
inline void sieve(int n) {
memset(isp, true, sizeof(isp));
isp[1] = false;
for (int i = 2; i <= n; ++i) {
if (isp[i])
pri[++pcnt] = i;
for (int j = 1; j <= pcnt && i * pri[j] <= n; ++j) {
isp[i * pri[j]] = false;
if (!(i % pri[j]))
break;
}
}
}
筛约数个数
\(d_i\) 表示 \(i\) 的约数个数, \(c_i\) 表示 \(i\) 的最小质因子出现次数
inline void prework(int n) {
memset(isp, true, sizeof(isp));
pcnt = 0;
isp[1] = false, d[1] = 1;
for (int i = 2; i <= n; ++i) {
if (isp[i])
pri[++pcnt] = i, d[i] = 2, c[i] = 1;
for (int j = 1; j <= pcnt && i * pri[j] <= n; ++j) {
isp[i * pri[j]] = false;
if (i % pri[j]) {
c[i * pri[j]] = 1;
d[i * pri[j]] = d[i] * 2;
} else {
c[i * pri[j]] = c[i] + 1;
d[i * pri[j]] = d[i] / c[i * pri[j]] * (c[i * pri[j]] + 1);
break;
}
}
}
}
筛约数和
\(f_i\) 表示 \(i\) 的约数和, \(g_i\) 表示 \(i\) 的最小质因子的 \(p^0 + p^1 + \cdots + p^k\)
inline void init(int n) {
memset(IsPrime, true, sizeof(IsPrime));
tot = 0;
g[1] = f[1] = 1;
for (int i = 2; i <= n; ++i) {
if (IsPrime[i])
prime[++tot] = i, g[i] = i + 1, f[i] = i + 1;
for (int j = 1; j <= tot && i * prime[j] <= n; ++j) {
IsPrime[i * prime[j]] = false;
if (i % prime[j]) {
f[i * prime[j]] = f[i] * f[prime[j]];
g[i * prime[j]] = prime[j] + 1;
}
else {
g[i * prime[j]] = g[i] * prime[j] + 1;
f[i * prime[j]] = f[i] / g[i] * g[i * prime[j]];
break;
}
}
}
}
扩展欧几里得
裴蜀定理:设 \(a, b\) 是不全为零的整数,对任意整数 \(x, y\) ,满足 \(\gcd(a, b) \mid ax + by\) ,且存在整数 \(x, y\) 使得 \(ax + by = \gcd(a, b)\) 。裴蜀定理也可以推广到多个整数的情况。
扩展欧几里得算法常用于求解方程 \(ax + by = \gcd(a, b)\) 的一组可行解。由裴蜀定理可知,该方程一定有解。
设:
由欧几里得定理 \(\gcd(a, b) = \gcd(b, a \bmod b)\) 可知:
将 \(a \bmod b\) 用 \(a - \lfloor \dfrac{a}{b} \rfloor \times b\) 带入,得:
展开得到:
所以:
实现:
int exgcd(int a, int b, int &x, int &y) {
if (b) {
int g = exgcd(b, a % b, y, x);
y -= a / b * x;
return g;
} else {
x = 1, y = 0;
return a;
}
}
对于不定方程:
若 \(c\) 不是 \(\gcd(a, b)\) 的倍数,则无解。已知扩欧可以求出
的一组整数特解,记为 \(\begin{cases} x = x_0 \\ y = y_0 \end{cases}\) ,可以得到该方程的一特解:
考虑构造原方程整数通解形式,设 \(d \in \mathbb{Q}\) ,则:
同时,通解需保证 \(x_1 + db, y_1 - da\) 均为整数。因为 \(x_1, y_1\) 均为整数,故只需保证 \(db, da\) 为整数即可。
令当 \(d\) 取到最小可能的正值时的 \(d_x = db, d_y = da\) ,那么有通解形式:
其中 \(s\) 为任意整数。
中国剩余定理
中国剩余定理(CRT)是用于求解形如:
的一元线性同余方程组,其中 \(m\) 两两互质。
实现
- 计算 \(M = \prod_{i = 1}^k m_i\) 。
- 对于第 \(i\) 个方程
- 计算 \(p_i = \dfrac{M}{m_i}\) 。
- 计算 \(p_i\) 在模 \(m_i\) 意义下的逆元 \(p_i^{-1}\) 。
- 计算 \(c_i = p_i p_i^{-1} \bmod M\) 。
- 方程组在模 \(M\) 意义下的唯一解即为 \(x = \sum_{i = 1}^k a_i c_i \pmod{M}\) 。
inline ll CRT() {
ll M = 1;
for (int i = 1; i <= n; ++i)
M *= m[i];
ll res = 0;
for (int i = 1; i <= n; ++i)
res = (res + mul(mul(a[i], M / m[i], M), inv(M / m[i], m[i]), M)) % M;
return res;
}
证明:只需证明上述算法解出的 \(x\) 均满足每一个方程即可。
当 \(i \not = j\) 时,显然有 \(p_j \equiv 0 \pmod{m_i}\) ,故 \(c_j \equiv p_j \equiv 0 \pmod{m_i}\) ,又因为 \(c_i \equiv p_i (p_i^{-1} \bmod m_i) \equiv 1 \pmod{m_i}\) ,所以有:
\[\begin{aligned} x &\equiv \sum_{j = 1}^k a_j c_j &\pmod{m_i} \\ &\equiv a_i c_i &\pmod{m_i} \\ &\equiv a_i p_i (p_i^{-1} \bmod m_i) &\pmod{m_i} \\ &\equiv a_i &\pmod{m_i} \end{aligned} \]所以上述算法解出的 \(x\) 均满足每一个方程。
另外,若 \(y \not = x\) ,则总存在 \(i\) 使得 \(x, y\) 在模 \(m_i\) 意义下不同余。
exCRT
模数不互质的CRT。
考虑两个方程的情况,设两个方程分别为 \(x \equiv a_1 \pmod{m_1}\) 与 \(x \equiv a_2 \pmod{m_2}\) 。转化为不定方程 \(x = m_1 p + a_1 = m_2 q + a_2\) ,其中 \(p, q \in \mathbb{Z}\) ,则有 $ m_1 p - m_2 q = a_2 - a_1$
由裴蜀定理,当 \(\gcd(m_1, m_2) \nmid (a_2 - a_1)\) 时方程无解。否则我们用 exgcd 求出一组可行解 \(p, q\) ,则 \(x \equiv m_1 p + a_1 \pmod{\operatorname{lcm}(m_1, m_2)}\) 。
拓展到多个方程,类似地按上述过程两两合并即可。
inline ll exCRT() {
pair<ll, ll> res = a[1];
auto merge = [](pair<ll, ll> a, pair<ll, ll> b) {
ll a1 = a.first, m1 = a.second, a2 = b.first, m2 = b.second;
ll x, y, g = exgcd(m1, m2, x, y), l = m1 / g * m2, c = ((a2 - a1) % l + l) % l;
if (c % g)
return make_pair(-1ll, -1ll);
return make_pair((a1 + mul(mul(x, c / g, l), m1, l)) % l, l);
};
for (int i = 2; i <= n; ++i) {
res = merge(res, a[i]);
if (res.first == -1)
break;
}
return res.first;
}
数论分块
注意到 \(\lfloor \dfrac{n}{x} \rfloor\) 在 \(x \in [1, n]\) 时的取值不超过 \(2 \sqrt{n}\) 种,对于某一些问题,考虑对一段 \(\lfloor \dfrac{n}{x} \rfloor\) 均相等的区间,我们可以直接得出该区间里的所有 \(x\) 对答案的贡献。
如果要实现整块一起统计,我们需要求出每一块的块头 \(l\) 和块尾 \(r\),则:
注意到每一块的 \(l\) 都可以由上一块的 \(r\) 推出,故我们继续讨论如何在已知 \(l\) 的情况下推出 \(r\) 。令 \(t = \lfloor \dfrac{n}{l} \rfloor\) ,容易得到
直接计算即可,时间复杂度 \(O(\sqrt{n})\) 。
for (int l = 1, r; l <= n; l = r + 1) {
r = n / (n / l);
// Calculate the contribution of [l, r]
}
扩展到二维甚至多维也是类似的,时间复杂度 \(O(k \sqrt{n})\) ,其中 \(k\) 为维度。
二维数论分块:
for (int l = 1, r; l <= min(n, m); l = r + 1) {
r = min(n / (n / l), m / (m / l));
// Calculate the contribution of [l, r]
}
Lucas 定理
普通形式
对于质数 \(p\) ,有:
一个特殊情况:\(\binom{i}{j} \bmod 2 = [j \subseteq i]\) 。
exLucas
处理模数非质数的情况。
Part 1
根据唯一分解定理,将模数 \(p\) 分解
显然,\(q_i^{k_i}\) 两两互质,构造同余方程组:
用 CRT 合并即可得出答案。
Part 2
问题转化为求 \(\dbinom{n}{m} \bmod q^k\) 的值(\(q\) 为质数)。注意到:
但是 \(m!\) 和 \((n - m)!\) 这两部分不一定能求出模 \(q^k\) 意义下的逆元,考虑把含 \(q\) 的项提取出来,即
此时下面的部分与 \(q^k\) 互质,就可以直接求逆元了。
Part 3
考虑如何求 \(\dfrac{n!}{q^x} \bmod q^k\) ,事实上手推不难发现:
Part 4
考虑如何求出 Part 2 中 \(x,y,z\) 的值。令 \(h(n)\) 为 \(n!\) 中 \(q\) 的次数,则:
原根相关
阶
若满足同余式 \(a^n \equiv 1 \pmod{m}\) 的最小正整数 \(n\) 存在,则称 \(n\) 为 \(a\) 模 \(m\) 的阶,记作 \(\delta_m(a)\) 。
性质:
- \(a, a^2, \cdots, a^{\delta_m(a)}\) 模 \(m\) 两两不同余。
- 若 \(a^n \equiv 1 \pmod{m}\) ,则 \(\delta_m(a) \mid n\) 。
- 推论:若 \(a^p \equiv a^q \pmod{m}\) ,则 \(p \equiv q \pmod{\delta_m(a)}\) 。
- 设 \(\gcd(a, m) = \gcd(b, m) = 1\) ,则 \(\delta_m(a, b) = \delta_m(a) \delta_m(b)\) 的充要条件是 \(\gcd(\delta_m(a), \delta_m(b)) = 1\) 。
- 若 \(\gcd(a, m) = 1\) ,则 \(\delta_m(a^k) = \dfrac{\delta_m(a)}{\gcd(\delta_m(a), k)}\) 。
原根
若 \(\gcd(g, m) = 1\) 且 \(\delta_m(g) = \varphi(m)\) ,则称 \(g\) 为模 \(m\) 的原根。
- 原根存在定理:\(m\) 存在原根当且仅当 \(m = 2, 4, p^\alpha, 2p^\alpha\) ,其中 \(p\) 为奇素数。
- 原根个数:若 \(m\) 有原根,则数量为 \(\varphi(\varphi(m))\) 。
- 原根判定定理:设 \(m \geq 3\) 且 \(\gcd(g, m) = 1\) ,则 \(g\) 是模 \(m\) 的原根的充要条件是:对于 \(\varphi(m)\) 的每个质因数 \(p\) ,都有 \(g^{\frac{\varphi(m)}{p}} \not \equiv 1 \pmod{m}\) 。
找原根直接暴力找就行了。
杂定理
- Wilson 定理:对于素数 \(p\) ,有 \((p - 1)! \equiv -1 \pmod{p}\) 。
- Legendre 公式:\(n!\) 中含有的素数 \(p\) 的幂次 \(v_p(n!) = \sum_{i = 1}^{\infty} \lfloor \dfrac{n}{p^i} \rfloor = \dfrac{n - S_p(n)}{p - 1}\) ,其中 \(S_p(n)\) 为 \(p\) 进制下 \(n\) 的各个数位的和。
- Kummer 定理:\(p\) 在组合数 \(\dbinom{n}{m}\) 的幂次等于 \(p\) 进制下 \(n - m\) 需要借位的次数,即 \(v_p \left( \dbinom{n}{m} \right) = \dfrac{S_p(m) + S_p(n - m) - S_p(n)}{p - 1}\) 。
- 等价的,\(p\) 在组合数 \(\dbinom{n + m}{n}\) 的幂次等于 \(p\) 进制下 \(n + m\) 的进位次数