数论

Miller-Rabin

先判掉 \(2\)\(n - 1 = 2^rd\),取 \(1 \le a < n\)。若 \(n\) 为质数,则 \(a^d \equiv 1 \pmod{n}\)\(\exist 0 \le i < r,\ a^{2^id} \equiv n - 1 \pmod{n}\) 至少一条成立,多次检测。

代码
bool isp(ll n) {
    if (n <= 1) return false;
    if (n <= 3) return true;
    if (n % 2 == 0) return false;
    int r = __builtin_ctzll(n - 1);
    ll d = (n - 1) >> r;
    for (auto a : {2, 325, 9375, 28178, 450775, 9780504, 1795265022}) {
        if (a % n == 0) continue;
        ll v = qpow(a, d, n);
        if (v == 1) continue;
        bool ok = false;
        for (int i = 0; i < r; i++) {
            if (v == n - 1) {
                ok = true;
                break;
            }
            v = i128(v) * v % n;
        }
        if (!ok) return false;
    }
    return true;
}

CRT & exCRT

\(n\) 个方程 \(x \equiv a_i \pmod{m_i}\)\(m_i\) 两两互质。

\(M = \prod m_i\),先解形如

\[\begin{cases} x_i \equiv 0 \pmod{\frac{M}{m_i}} \\ x_i \equiv 1 \pmod{m_i} \end{cases} \]

\(n\) 个方程组,则 \(x \equiv \sum a_i x_i \pmod{M}\)

不保证 \(m_i\) 互质时,考虑合并 \(x \equiv a \pmod{b}\)\(x \equiv c \pmod{d}\)

\[\begin{align*} x = bs + a &= dt + c \\ bs - dt &= c - a \end{align*} \]

用 exgcd 解出一组解 \(s_0, t_0\),则

\[s = s_0 + k \cdot \frac{d}{\gcd(b, d)} \]

带入 \(x = bs + a\),得

\[x = b\left(s_0 + k \cdot \frac{d}{\gcd(b, d)}\right) + a = bs_0 + k \cdot \operatorname{lcm}(b, d) + a \equiv bs_0 + a \pmod{\operatorname{lcm}(b, d)} \]

依次合并 \(n\) 个方程即可。

代码
bool merge(ll& a, ll& b, ll c, ll d) {
    ll s, t, g = exgcd(b, d, s, t);
    if ((c - a) % g) return false;
    ll lcm = b / g * d;
    s = i128(s) * ((c - a) / g) % lcm;
    if (s < 0) s += lcm;
    a = (i128(b) * s + a) % lcm, b = lcm;
    return true;
}

只判断是否有解且答案会爆 ll:设 \(m_i\) 的标准分解为 \(p_1^{e_1}p_2^{e_2} \dots p_k^{e_k}\),由 CRT,\(x \equiv a_i \pmod{m_i}\) 可拆成

\[\begin{cases} x \equiv a_i \pmod{p_1^{e_1}} \\ x \equiv a_i \pmod{p_2^{e_2}} \\ \vdots \\ x \equiv a_i \pmod{p_k^{e_k}} \end{cases} \]

将所有拆出的方程按模的质数分组,不同组之间模数互质,不会矛盾,所以只需检查每组内是否有解即可。

代码
void solve() {
    int n;
    cin >> n;
    map<int, vector<pair<int, int>>> mp;
    for (int i = 1; i <= n; i++) {
        int a, m;
        cin >> a >> m;
        for (int j = 2; j * j <= m; j++) {
            if (m % j == 0) {
                int pw = 1;
                while (m % j == 0) m /= j, pw *= j;
                mp[j].push_back({pw, a % pw});
            }
        }
        if (m != 1) mp[m].push_back({m, a % m});
    }
    for (auto it : mp) {
        auto eqs = it.second;
        int v = max_element(eqs.begin(), eqs.end())->second;
        for (auto eq : eqs) {
            if (v % eq.first != eq.second) {
                cout << "No\n";
                return;
            }
        }
    }
    cout << "Yes\n";
}

BSGS

\(a^x \equiv b \pmod{p}\)\(p\) 为质数。

由费马小定理 \(a^{p - 1} \equiv a^0 \pmod{p}\) 可将解的范围缩小至 \([0, p - 1)\)。设置一个阈值 \(s\),将 \(0 \sim s - 1\) 设为第 \(1\) 组,\(s \sim 2s - 1\) 设为第 \(2\) 组,以此类推。把 \(a^0, a^1, \ldots, a^{s - 1}\) 扔进 map,枚举每一组,查询 \(\frac{b}{a^{is}}\) 即可。时间复杂度在 \(s = \sqrt{p}\) 时取到最小值 \(O(\sqrt{p} \log \sqrt{p})\)

代码
int bsgs(int a, int b, int p) {
    int s = sqrt(p) + 1;
    map<int, int> mp;
    int pw = 1;
    for (int i = 0; i < s; i++) mp[pw] = i, pw = ll(pw) * a % p;
    int inv = qpow(qpow(a, s, p), p - 2, p);
    for (int i = 0; i < s; i++) {
        if (mp.count(b)) return i * s + mp[b];
        b = ll(b) * inv % p;
    }
    return -1;
}

狄利克雷卷积

  • 定义:\((f * g)(n) = \sum_{d \mid n} f(d)g(\frac{n}{d})\)

  • 有交换律、结合律、分配律。

  • \(f\)\(g\) 均为积性函数,则 \(f * g\) 为积性函数。

  • \(\varepsilon * f = f\)\(\varepsilon(n) = [n = 1]\)

  • \(\mu * \mathbf{1} = \varepsilon\)\(\mathbf{1}(n) = 1\)

  • \(\varphi * \mathbf{1} = \operatorname{id}\)\(\operatorname{id}(n) = n\)
    证明:对任意 \(d \mid n\)\(\gcd(x, n) = d \iff \gcd(\frac{x}{d}, \frac{n}{d}) = 1\),所以 \(1 \sim n\) 中有 \(\varphi(\frac{n}{d})\)\(x\) 满足 \(\gcd(x, n) = d\),所以 \((\varphi * \mathbf{1})(n) = \sum_{d \mid n} \varphi(d) = \sum_{d \mid n} \varphi(\frac{n}{d}) = n = \operatorname{id}(n)\)

  • \(\mu * \operatorname{id} = \varphi\)

  • \(f = g * \mathbf{1} \iff g = f * \mu\)(莫比乌斯反演)

posted @ 2026-04-01 11:47  Sunsoak  阅读(5)  评论(2)    收藏  举报