數論篇5——數論四大定理


數論四大定理:

  • 威爾遜定理
  • 歐拉定理
  • 孫子定理(中國剩余定理)
  • 費馬小定理

1.威爾遜定理

在初等數論中,威爾遜定理給出了判定一個自然數是否為素數的充分必要條件。

當且僅當$p$為素數時

$(p-1)!\equiv -1(mod\ p)$

簡單點說就是,若$p$為質數,則$p$能被 $(p-1)!+1$ 整除

但是由於階乘是呈爆炸增長的,其結論對於實際使用不太多。

證明

首先,可以明確

$(p-1)\equiv -1(mod\ p)$

根據同余式的性質,我們只需要證明

$(p-2)!\equiv 1(mod\ p)$

這個式子突然就有點熟悉了,看下逆元的定義

$a\cdot a^{-1}\equiv 1(mod\ p)$

我們考慮其實就是對於 $1,2,3,...,p−2 $去找模$p$意義下的逆元,而1的逆元就是1,不需要考慮

然后根據

$x^{2}\equiv 1(mod\ p)$

可以解得

$x_{1}=1,x_{2}=p-1$ 

意思就是只有1,$p-1$在模$p$意義下的逆元是自己,然而這兩個數已經被我們安排了,然后逆元還有唯一性互反性。

那么這些數自然是一一對應,所以$(p-2)!\equiv 1(mod\ p)$成立。

2.歐拉定理

 如果$n,a$為正整數,且$n,a$互質,則$a^{\varphi(n)}=1(mod\ n)$

歐拉函數的定義與實現

證明

將1~n中與n互質的數按順序排布:

$x_{1},x_{2},x_{3}...x_{\varphi(n)}$ 

我們考慮這么一些數:

$m_{1}=a*x_{1};m_{2}=a*x_{2};m_{3}=a*x_{3}...m_{\varphi(n)}=a*x_{\varphi(n)}$

需要兩個引理,證明就不詳細展開了。

1)這些數中的任意兩個都不模n同余

2)這些數除n的余數都與n互質

由1)和2)可知

數$m_{1},m_{2},m_{3}...m_{\varphi(n)}$(如果將其次序重新排列)必須相應地同余於$x_{1},x_{2},x_{3}...x_{\varphi(n)}$ 

故得出:

$m_{1}*m_{2}*m_{3}...m_{\varphi(n)}\equiv x_{1}*x_{2}*x_{3}...x_{\varphi(n)}(mod\ n)$

$a^{\varphi(n)}(x_{1}*x_{2}*x_{3}...x_{\varphi(n)})\equiv x_{1}*x_{2}*x_{3}...x_{\varphi(n)}(mod\ n)$

$K(a^{\varphi(n)}-1)\equiv 0(mod\ n) $這里$K=x_{1}*x_{2}*x_{3}...x_{\varphi(n)}$

可知

$K(a^{\varphi(n)}-1)$

被n整除,但$K$中的因子都與$n$互質,所以$K$與$n$互質。那么

$a^{\varphi(n)}-1$

必須能被$n$整除,即

$a^{\varphi(n)}-1\equiv 0(mod\ n) $

$a^{\varphi(n)}\equiv 1(mod\ n) $

得證。

3.費馬小定理

能看出來,歐拉定理是費馬小定理的推廣,所以歐拉定理也叫費馬-歐拉定理,就不詳細展開了。

順便一提一下,費馬大定理:

當整數$n >2$時,關於$x, y, z$的方程$ x^{n} + y^{n} = z^{n}$沒有正整數解。

4.中國剩余定理(孫子定理)

問題描述

  “今有物不知其數,三三數之余二,五五數之余三,七七數之余二。問物幾何?”

轉換成數學語言,就是求解一次同余式組

\begin{cases}
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{cases}

其中$a_i, m_i$均為正數,模數$m_i$兩兩互素。

定理

令$M=\prod_{i=1}^{n}m_{i}$,即$M$是$m_i$的最小公倍數

$e_i$為$\frac{M}{m_i}\cdot e_i\equiv 1(mod \ m_i)$的最小非負整數解

則有對於原方程組有唯一解

$x=\sum_{i=1}^{k}a_ie_i \frac{M}{m_i} (mod\ M)$

代碼實現:

void exgcd(int a, int b, int& x, int& y)
{
    if (b == 0) { x = 1; y = 0; return; }
    exgcd(b, a % b, x, y);
    int temp = x;
    x = y; y = temp - a / b * y;
}

int crt(int* a, int* m, int k)
{
    int res, x, y, M = 1;
    for (int i = 1; i <= k; ++i) M *= m[i];
    for (int i = 1; i <= k; ++i)
    {
        exgcd(M / m[i], m[i], x, y);
        if (x < 0)
            x += m[i];
        res = (res + M / m[i] * x * a[i]) % M;
    }
    return res % M;
}

模板題

https://www.luogu.org/problemnew/solution/P3868

#include <iostream>
#include <fstream>
using namespace std;

typedef long long LL;

LL m[10], a[10], k;
//數據可能會爆long long
LL quick_mult(LL a, LL b, LL M) {
    LL res = 0;
    while (b) {
        if (b & 1)
            res = (res + a) % M;
        a = (a + a) % M;
        b >>= 1;
    }
    return res % M;
}
void ex_gcd(LL a, LL b, LL&x, LL&y) {
    if (b == 0) {
        x = 1; y = 0;
        return;
    }
    ex_gcd(b, a % b, x, y);
    LL temp = x;
    x = y;
    y = temp - a / b * y;
}

LL crt() {
    LL M = 1;
    LL e[10];
    LL except_mi[10];
    for (int i = 0; i < k; i++) {
        M *= m[i];
    }
    for (int i = 0; i < k; i++) {
        LL x,y;
        ex_gcd(M / m[i], m[i], x, y);
        if (x < 0)
            x += m[i];
        e[i] = x;

    }

    LL res = 0;
    for (int i = 0; i < k; i++) {
        (a[i] % m[i] + m[i]) % m[i];//a[i]可能為負數,根據同余性質,取正
        res = res % M + quick_mult(e[i], quick_mult(M / m[i], a[i], M), M);
    }
    return res % M;
}

int main() {
#ifdef LOCAL
    fstream cin("data.in");
#endif // LOCAL
    cin >> k;
    for (int i = 0; i < k; i++) {
        cin >> a[i];
    }
    for (int i = 0; i < k; i++) {
        cin >> m[i];
    }
    cout << crt();
    return 0;
}
View Code

 


免責聲明!

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



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