淺談數論


淺談數論

隨手寫寫,就當是復習

順序隨機(因為我太菜了,所以只能想到什么寫什么)

gcd

__gcd(a,b)

or

\(\gcd(a, b) = \gcd(a, b - a) = \gcd (b,a \% b)\)

inline int gcd(int a, int b)
{
	if (!b) return a;
	return gcd(b, a % b);
}

lcm

inline int lcm(int a, int b)
{
	return a / gcd(a, b) * b;
}

擴展歐幾里得

求解關於 \(x,y\) 的不定方程

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

根據歐幾里得定理,\(\gcd(a, b) = \gcd(b, a\mod b)\)

於是

\(ax + by = \gcd(b, a \mod b) = bx + (a \mod b) y\)

\(\begin{align*} ax + by &= bx + (a - \lfloor \frac a b \rfloor \cdot b)y\\ &= bx + ay - \lfloor \frac a b \rfloor \cdot by\\ &= ay + b(x - \lfloor \frac a b \rfloor y) \end{align*}\)

於是

\(\left\{ \begin{align*} x' &= y\\y' &= x - \lfloor \frac a b \rfloor y \end{align*} \right.\)

inline int exgcd(int a, int b, int &x, int &y)
{
    if (!b)
    {
        x = 1, y = 0;
        return a;
    }
    int g = exgcd(b, a%b, x, y);
    int xx = y, yy = x - a / b * y;
    x = xx, y = yy;
    return g;
}

求解關於 \(x\) 的線性同余方程

\(ax \equiv b \mod m\)

原式等價於

\[ax + k_1m = b + k_2m\\ \Leftrightarrow ax + m(k_1 - k_2) = b\\ 令 g \leftarrow \gcd(a,m)\\ \Leftrightarrow a \cdot \frac g b x + m \cdot \frac g b (k_1 - k_2) = g \]

當且僅當 \(b \mid g\) 有解,直接用 exgcd 求解即可

線性篩素數

for (re int i = 2; i <= n; ++i)
{
    if (!vis[i]) pri[++num] = i;
    for (re int j = 1; j <= num && pri[j] * i <= n; ++j)
    {
        vis[i * pri[j]] = 1;
        if (i % pri[j] == 0) break;
    }
}

歐拉函數

Definition : \(a, b\) 互質是指 \(\gcd(a, b) = 1\)

求解 \(\varphi(n)\)

數學歸納法:

  • \(n\) 為質數時 \(\varphi (n) = n - 1\)

  • \(n\) 為合數時:

    1. \(n = p^a\)

      此時 \(n\) 的質因數只有 \(p\) ,那么在 \([1, p^a]\) 內不與 \(p^a\) 互質的數只有 \(p, 2p, 3p ...\)\(\begin{align*} \frac {p^a} p \end{align*}\)

      小容斥一下,\(\begin{align*} \varphi(n) = p^a - \frac {p^a} p \end{align*}\)

      最終 \(\begin{align*} \varphi(n) = p^a (1 - \frac 1 p) \end{align*}\)

    2. others:

      根據算數基本定理,\(\begin{align*} n = \prod p_i^{a_i} \end{align*}\)

      又根據 \(y = \varphi (n)\) 為積性函數,\(\begin{align*} \varphi(n) = \varphi(\prod p_i^{a_i}) = \prod \varphi(p_i^{a_i}) = \prod p_i^a (1 - \frac 1 {p_i}) = \prod {p_i^a} \prod(1 - \frac 1 {p_i}) \end{align*}\)

      最終 \(\begin{align*} \varphi(n) = n\prod(1 - \frac 1 {p_i}) \end{align*}\)

線性篩歐拉函數

  • Theorem 1 :若 \(n\) 為質數 \(\varphi(n) = n - 1\)

  • Theorem 2 :若 \(p \mid n\),則 \(\varphi(n \cdot p ) = \varphi (n) \cdot p\)

    Proof :

    \(\begin{align*} \because \varphi(n \cdot p) = n \cdot p \prod_i (1 - \frac 1 p_i), \varphi(n) = n \prod_i (1 - \frac 1 p_i) \end{align*}\)

    \(\begin{align*} \therefore \frac {\varphi(n \cdot p)} {\varphi(n)} = p \end{align*}\) ,證畢

  • Theorem 3 :若 \(p \nmid n\),則 \(\varphi(n \cdot p ) = \varphi(n) \cdot (p - 1)\)

    Proof :

    \(\varphi (n \cdot p ) = \varphi (n) \cdot \varphi (p) = \varphi(n) \cdot (p - 1)\) ,證畢

phi[1] = 1;
for (re int i = 2; i <= n; ++i)
{
    if (!vis[i]) pri[++num] = i, phi[i] = i - 1;
    for (re int j = 1; j <= num && pri[j] * i <= n; ++j)
    {
        vis[pri[j] * i] = 1;
        if(i % pri[j] == 0)
        {
            phi[i * pri[j]] = phi[i] * pri[j];//Theorem 2
            break;
        }
        phi[i * pri[j]] = phi[i] * (pri[j] - 1);
    }
}

歐拉定理

\(a\)\(n\) 互質,則 \(a^{\varphi(n)} \equiv 1 \mod n\),證明不會

歐拉定理推論

\(a\)\(n\) 互質,則 \(a^b \equiv a^{b \mod \varphi(n)} \mod n\)

Proof :

​ 設 \(b = q \varphi(n) + r\),則 \(r = b \mod \varphi(n)\)

​ 於是 \(a^b = a^{q\varphi(n) + r} = a^{\varphi(n)^q} \cdot a^r\)

​ 根據歐拉定理,由於 \(a\)\(n\) 互質,於是 \(a^{\varphi(n)} \equiv 1 \mod n\)

​ 於是 \(a^b\equiv 1^q \cdot a^r \equiv a^{b \mod \varphi(n)} \mod n\),證畢

\(a\)\(n\) 不互質,則 \(\begin{align*} a^b \equiv a^{b \mod \varphi(n) + \varphi(n)} \mod n \end{align*}\),(當然,\(b > \varphi(n)\) ),證明不會

歐拉反演

\(\sum_{d\mid n} \varphi(d) = n\) 證明不會(這么多的證明我都不會,我真是太菜了/kk)

擴展中國剩余定理(EXCTR)

我不會中剩(CTR)

求解線性同余方程組:

\(\left\{ \begin{align*} x&\equiv a_1 \mod m_1\\ x&\equiv a_2 \mod m_2\\ x&\equiv a_3 \mod m_3\\ &...\\ x&\equiv a_n \mod m_n \end{align*} \right.\)

其中 \(m_1, m_2, m_3... m_n\) 可以不互質

設當前求出的解 \(x_{k-1}\) 滿足前 \(k - 1\) 個方程,\(M\)\(\begin{align*} LCM_{i = 1}^{k -1 } m_i \end{align*}\)

則第 \(k\) 個方程的解 \(x_k = x_{k-1} + tM\) 需滿足 \(x_k \equiv a_k \mod m_k\)

即求解 \(t\in \mathbb{Z}\),滿足 \(tM \equiv a_k - x_{k-1} \mod m_k\)

方程中 \(x_{k-1}, M, a_k, m_k\) 都為已知量,只需用擴展歐幾里得求解 \(n\) 次線性同余方程即可

n = read();
int m = read(), a = read();
X = a, M = m;
for (re int i = 2; i <= n; ++i)
{
    m = read(), a = read();
    int t, y;
    int b = ((a - X) % m + m) % m, g = exgcd(M, m, t, y);
    t = t * (b / g) % m;
    X = X + t * M;
    M = M / g * m;
    X = (X + M) % M;
}

逆元

Definition:若 \(ax \equiv 1 \mod m\),則稱 \(x\)\(a\) 在模 \(m\) 意義下的逆元,當且僅當 \(a\)\(m\) 互質的情況下才存在逆元

  1. 根據定義,求解用擴展歐幾里得解線性同余方程求得逆元

  2. 歐拉定理求逆元 :根據 \(\begin{align*} a^{\varphi(n)} \equiv 1 \mod n \end{align*}\),於是 \(a \cdot a^{\varphi(n) - 1} \equiv 1 \mod n\)\(a^{\varphi(n) - 1}\) 即為逆元

  3. 費馬小定理求逆元 :

    Definition : 當 \(n\) 為質數時,\(a^{n - 1} \equiv 1 \mod n\)

    Proof :

    ​ 因為 \(m\) 為質數,於是 \(\varphi(n) = n - 1\)

    ​ 再根據歐拉定理可得 \(a^{\varphi(n)} = a^{n -1 } \equiv 1 \mod n\),證畢

    因此 \(a \cdot a^{n - 2} \equiv 1 \mod n\)\(a^{n - 2}\) 即為逆元

線性求逆元

設當前為 \(i\),模數為 \(m\),已知 \([inv_1,inv_{i-1}]\),求 \(inv_i\)

\(m = qi + r\)\(q,r\in \mathbb{Z} ,r<i\),則 \(\begin{align*} q = \lfloor \frac m i \rfloor \end{align*}\)\(r = m \% i\)

於是 \(m = qi + r \equiv 0 \mod m\)

兩邊同時除以 \(i \cdot r\),有 \(q \cdot inv[r] + inv[i] \equiv 0 \mod m\)

於是 \(inv[i] \equiv -q \cdot inv[r] \mod m\)

帶入 \(q,r\) 即為 :\(\begin{align*}i nv[i] \equiv -\lfloor \frac m i \rfloor \cdot inv[m \% i]\mod m \end{align*}\)

為了保證 \(inv[i]\) 為正整數,\(\begin{align*}i nv[i] = m - \lfloor \frac m i \rfloor \cdot inv[m \% i] \% m \end{align*}\)

inv[1] = 1;
for (re int i = 2; i <= n; ++i)
	inv[i] = P - P / i * inv[P % i] % P;

線性求階乘逆元

由於 \(\begin{align*} fac[i] = fac[i - 1] \cdot i \% P \end{align*}\)

於是可得 \(fac[i] \equiv fac[i - 1] \cdot i \mod P\)

兩邊同時除以 \(fac[i] \cdot fac[i - 1]\),得 \(inv[fac[i - 1]] \equiv inv[fac[i]] \cdot i \mod P\)

於是可得 \(inv[fac[i]] = inv[fac[i + 1]] \cdot (i+1) %P\)

inv[n] = ksm(n, P - 2);//用快速冪求逆元(費馬小定理)
for (re int i = n - 1; i; --i)
    inv[i] = inv[i + 1] * (i + 1) % P;

線性求任意數逆元

給定 \(n\) 個數 \(a_1,a_2,a_3...a_n\),對於每一個 \(1 \le i \le n\),求 \(a_i\) 的在模 \(P\) 意義下的逆元

設當前求 \(a_i\) 的逆元,\(\begin{align*} M = \prod_{i = 1}^n a_i \end{align*}\)\(\begin{align*}pm ul_i = \prod_{j = 1} ^ i a_j \end{align*}\)\(\begin{align*} smul = \prod _{j = i} ^ n a_j \end{align*}\)

則有 \(\begin{align*} pmul_{i-1} \cdot a_i \cdot smul_{i + 1} \equiv M \mod P \end{align*}\)

老規矩,兩邊同時除以 \(a_i \cdot M\),得 \(\begin{align*}i nv[M] \cdot pmul_{i-1} \cdot smul_{i + 1} \equiv inv[a_i] \mod P \end{align*}\)

預處理出 \(pmul_i\)\(smul_i\),用 \(O(logM)\) 的時間復雜度算出 \(inv[M]\),那么對於每個 \(a_i\),可以用 \(O(1)\) 的時間復雜度算出 \(inv[a_i]\) 總時間復雜度為 \(O(n)\)

pmul[0] = smul[n + 1] = M = 1;
for (re int i = 1; i <= n; ++i)
{
    M = M * i % P;
    pmul[i] = pmul[i - 1] * i % P;
}
for (re int i = n; i; --i) smul[i] = smul[i + 1] * i % P;
int invM = ksm(M, P - 2);
for (re int i = 1; i <= n; ++i)
    inv[i] = invM * pmul[i - 1] % P * smul[i + 1] % P;

組合數學

\(\begin{align*} A_n^m = \frac {n!} {(n - m)!} \end{align*}\)\(\begin{align*} C_n^m = \frac {n!}{m!(n-m)!} \end{align*}\)

求解組合數用公式算或用楊輝三角遞推,具體如何選擇看情況

Lucas定理

\(n,m \ge P\) 時,由於我們不能直接對 \(n, m\) 取模算組合數,所以就需要用到Lucas定理 :

\(\begin{align*} C_n^m = C_{n \% P} ^ {m \% P} \cdot C_{n / p} ^ {m / p} \end{align*}\) ,證明不會

容斥原理

\(f_i\) 表示滿足 \(i\) 個性質的方案數

\(g_i\) 表示滿足至少 \(i\) 個性質的方案數

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

莫比烏斯函數

Definition :

​ 設 \(\begin{align*} n = \prod_{i = 1} ^ m p_i^{c_i} \end{align*}\)

​ 則

\[\mu(n) = \left\{ \begin{align*} 0&\qquad \exists i \in [1, m], c_i > 1\\ 1&\qquad m \% 2=0,\forall i \in [1,m], c_i = 1\\ -1&\qquad m \% 2 = 1, \forall i \in [1,m],c_i = 1 \end{align*} \right. \]

​ 更通俗

\[\mu(n) = \left\{ \begin{align*} 0&\qquad n能被某個質數的平方整除\\ 1&\qquad n是偶數個不同質數的積\\ -1&\qquad n是奇數個不同質數的積 \end{align*} \right. \]

線性篩莫比烏斯函數

根據定義很好理解,與線性篩歐拉函數很相似

mu[1] = 1;
for (re int i = 2; i <= n; ++i)
{
    if (!vis[i]) pri[++num] = i, mu[i] = -1;
    for (re int j = 1; j <= num && pri[j] * i <= n; ++j)
    {
        vis[i * pri[j]] = 1;
        if(i % pri[j] == 0)
        {
            mu[i * pri[j]] = 0;
            break;
        }
        mu[i * pri[j]] = -mu[i];
    }
}

莫比烏斯反演

\(\begin{align*} \sum_{d \mid n} \mu(d) = [n = 1] \end{align*}\)(太菜了,只會這一種)

  • 運用 :求 \(\begin{align*} \sum_\limits{i = 1} ^ \limits{n} \sum _\limits{j = 1} ^ \limits{m} [\gcd(i,j)=1], (n \le m) \end{align*}\) 的值

    原式

    \(\begin{align*} &=\sum_\limits{i = 1} ^ \limits{n} \sum _\limits{j = 1} ^ \limits{m} \sum _\limits{d \mid (i, j)} \mu(d) \\ &= \sum_\limits{i = 1} ^ \limits{n} \sum _\limits{j = 1} ^ \limits{m} \sum _\limits{d \mid i, d \mid j} \mu(d) \\ &= \sum _ \limits{d = 1} ^ \limits{n} \mu(d) \sum _ \limits{d \mid i} \sum _ \limits{d \mid j} 1 \\ &= \sum _ \limits{d = 1} ^ \limits{n} \mu(d) ( \sum _ \limits{d \mid i} 1 ) (\sum _ \limits {d \mid j} 1), (i \in [1,n], j \in [1, m]) \\ &= \sum _ \limits{d = 1} ^ \limits{n} \mu (d) \lfloor \frac n d \rfloor \lfloor \frac m d \rfloor \end{align*}\)

    然后就可以 \(O(n+n)\) 解決,加上整出分塊只需 \(O(n+\sqrt n)\) 即可解決

大佬的莫反blog

整除分塊

\(\begin{align*} \sum _ \limits{i =1} ^ \limits{n} \lfloor \frac n i \rfloor \end {align*}\) 的值

​ 根據整除商的值呈塊狀分布,設共有 \(m\) 塊,每塊的左右端點分別為 \(l_i,r_i,(i\in [1, m] )\) ,則第 \(i\) 塊的值為 \(\begin{align*} \lfloor \frac n j \rfloor,j \in [l_i , r_i] \end{align*}\)

​ 則 \(\begin{align*} \sum _ \limits{i =1} ^ \limits{n} \lfloor \frac n i \rfloor = \sum _{i = 1} ^ m (r_i - l_i + 1) \cdot \lfloor \frac n {l_i} \rfloor \end {align*}\)

​ 現在已知第 \(i\) 塊的左端點 $l _i $ ,需求右端點 \(r_i\)

​ 根據左端點,可以求得該塊的值為 \(\begin{align*} \lfloor \frac n {l_i} \rfloor \end{align*}\),那么對於 \(\forall j \in [l_i, r_i]\),都滿足 \(\begin{align*} j \cdot \lfloor \frac n {l_i} \rfloor \le n \end{align*}\) ,特別地,當 \(j = r_i\) 時,\(j \mid n\)\(\begin{align*} j \cdot \lfloor \frac n {l_i} \rfloor = n \end{align*}\)

​ 於是可得 \(\begin{align*} r_i = \frac n { \lfloor \frac n {l_i} \rfloor } \end{align*}\),而 \(l_{i + 1} = r_i + 1\)

​ 由於最多只能分 \(\sqrt n\) 塊,每塊計算復雜度為 \(O(1)\) ,於是總時間復雜度為 \(O(\sqrt n)\)

int ans = 0;
for (re int l = 1, r; l <= n; l = r + 1)
{
    r = n / (n / l);
    ans = ans + (r - l + 1) * (n / l);
}

神仙的整除分塊blog

多項式與生成函數

這個只能請教多項式代師HS了,蒟蒻根本沒學懂

杜教篩

用於快速求積性函數前綴和,詳見

\[\begin{aligned} &S(n) = \sum_{i = 1} ^ n f(i) \\ &g(1)S(n) = \sum_{i = 1} ^ n (f * g)(i) - \sum_{i = 2} ^ n g(i)S(\lfloor \frac ni\rfloor) \end{aligned} \]

inline int sum_g(const int &x) // 求 g(1) + ... + g(x)
{
    ...
}
inline int sum_fg(const int &x) // 求 (f * g)(1) + .. + (f * g)(x)
{
    ...
}
inline int sum_f(const int &x) // 求 S(x)
{
    if (x <= M) return S[x]; // 預處理的值
    if (mp[x]) return mp[x]; // map 記憶化
    int ans = sum_fg(x); // 求 f * g 的前綴和
    for (int l = 2, r; l <= x; l = r + 1) // 注意不要從 1 開始
    {
        r = x / (x / l); // 整出分塊
        int res = sum_g(r) - sum_g(l - 1); // g(l) + .. + g(r)
        ans = (ans - res * sum_f(x / l));
    }
    return mp[x] = ans;
}

還有太多內容蒟蒻一時也想不起來,所以到這里就結束了。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM