数论杂记

数论杂记

数论函数

数论函数是指这样一类函数:其定义域是正整数,值域是一个数集。

定义两个数论函数的加法,为逐项相加,即 \((f + g)(n) = f(n) + g(n)\)

定义数乘这个数和每一项都相乘,即 \((xf)(n) = x \times f(n)\)

常见数论函数

\[1(x) = 1 \\ \epsilon(x) = [x = 1] \\ id(x) = x \\ id^k(x) = x^k \\ \sigma_0(x) = \sum_{d | x} 1 \\ \sigma(x) = \sum_{d | x} d \\ \sigma_k(x) = \sum_{d | x} d^k \]

常见数论函数的性质

\[\sum_{i = 1}^n \sigma(i) = \sum_{i = 1}^n \lfloor \dfrac{n}{i} \rfloor \]

证明:考虑每个因数的贡献即可。

\[\sigma(ij) = \sum_{x | i} \sum_{y | j} [\gcd(x, y) = 1] \]

证明:考虑把每个因子一一映射,如果 \(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\) 必须互质。

推广:

\[\sigma(ijk) = \sum_{a | i} \sum_{b | j} \sum_{c | k} [\gcd(a, b) = 1] [\gcd(b, c) = 1] [\gcd(a, c) = 1] \]

积性函数

定义

积性函数

对于函数 \(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)\) 均为积性函数,则以下函数也为积性函数:

\[h(n) = f(n^p) \\ h(n) = f^p(n) \\ h(n) = f(n) g(n) \\ h(n) = \sum_{d | n} f(d) g(\dfrac{n}{d}) \]

线性筛

线性筛的时间复杂度是由每个数都会被最小的质因子标记的。

一般的,对于积性函数 \(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 卷积式:

\[\sigma_0 = 1 * 1 \\ id = \varphi * 1 \\ \sigma = 1 * id = \sigma_0 * \varphi \\ 1 = \sigma_0 * \mu \\ \epsilon = \mu * 1 \\ \varphi = \mu * id \]

线性筛

线性筛的时间复杂度是由每个数都会被最小的质因子标记的。

一般的,对于积性函数 \(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)\) 的一组可行解。由裴蜀定理可知,该方程一定有解。

设:

\[ax_1 + by_1 = \gcd(a,b) \\ bx_2 + (a \bmod b)y_2 = \gcd(b, a \bmod b) \]

由欧几里得定理 \(\gcd(a, b) = \gcd(b, a \bmod b)\) 可知:

\[ax_1 + by_1 = bx_2 + (a \bmod b)y_2 \]

\(a \bmod b\)\(a - \lfloor \dfrac{a}{b} \rfloor \times b\) 带入,得:

\[ax_1 + by_1 = bx_2 + (a - \lfloor \dfrac{a}{b} \rfloor \times b)y_2 \]

展开得到:

\[ax_1 + by_1 = ay_2 + bx_2 - \lfloor \dfrac{a}{b} \rfloor \times by_2 = ay_2 + b(x_2 - \lfloor \dfrac{a}{b} \rfloor y_2) \]

所以:

\[\begin{cases} x_1 = y_2 \\ y_1 = x_2 - \lfloor \dfrac{a}{b} \rfloor y_2 \end{cases} \]

实现:

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;
    }
}

P5656 【模板】二元一次不定方程 (exgcd)

对于不定方程:

\[ax + by = c \]

\(c\) 不是 \(\gcd(a, b)\) 的倍数,则无解。已知扩欧可以求出

\[ax + by = \gcd(a,b) \]

的一组整数特解,记为 \(\begin{cases} x = x_0 \\ y = y_0 \end{cases}\) ,可以得到该方程的一特解:

\[\begin{cases} x_1 = \dfrac{x_0 c}{\gcd(a, b)} \\ y_1 = \dfrac{y_0 c}{\gcd(a, b)} \end{cases} \]

考虑构造原方程整数通解形式,设 \(d \in \mathbb{Q}\) ,则:

\[a(x_1 + db) + b(y_1 - da) = c \]

同时,通解需保证 \(x_1 + db, y_1 - da\) 均为整数。因为 \(x_1, y_1\) 均为整数,故只需保证 \(db, da\) 为整数即可。

令当 \(d\) 取到最小可能的正值时的 \(d_x = db, d_y = da\) ,那么有通解形式:

\[\begin{cases} x = x_1 + s d_x \\ y = y_1 - s d_y \end{cases} \]

其中 \(s\) 为任意整数。

中国剩余定理

中国剩余定理(CRT)是用于求解形如:

\[\begin{aligned} \begin{cases} x &\equiv a_1 \pmod{m_1} \\ x &\equiv a_2 \pmod{m_2} \\ &\vdots \\ x &\equiv a_k \pmod{m_k} \end{cases} \end{aligned} \]

的一元线性同余方程组,其中 \(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}\)

P1495 【模板】中国剩余定理(CRT)/ 曹冲养猪

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\),则:

\[Ans = \sum_{i=1}^{k} \lfloor \dfrac{n}{i} \rfloor = \sum_{[l,r]} (r-l+1)(\lfloor \dfrac{n}{l} \rfloor) \]

注意到每一块的 \(l\) 都可以由上一块的 \(r\) 推出,故我们继续讨论如何在已知 \(l\) 的情况下推出 \(r\) 。令 \(t = \lfloor \dfrac{n}{l} \rfloor\) ,容易得到

\[\begin{cases} r = \min(\lfloor \dfrac{n}{t} \rfloor,n) \ \ \ &(t \neq 0) \\ r = n \ \ \ &(t=0) \end{cases} \]

直接计算即可,时间复杂度 \(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]
}

原根相关

若满足同余式 \(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\) 的进位次数
posted @ 2024-08-30 10:00  我是浣辰啦  阅读(17)  评论(0编辑  收藏  举报