ACM数论笔记 基础数论

基础数论部分

整除

定义

a , b ∈ Z , a ≠ 0 , 若 ∃ q ∈ Z 使得 b = a q a,b\in Z,a\neq0,若\exist q \in Z 使得b=aq a,bZ,a=0,qZ使得b=aq则b可被a整除,记作 a ∣ b a\mid b ab,称b是a的倍数,a是b的约数

不能整除 a ∤ b a\nmid b ab

定理

  1. a ∣ b    ⟺    − a ∣ b    ⟺    a ∣ − b    ⟺    ∣ a ∣ ∣ ∣ b ∣ a\mid{b}\iff -a\mid{b} \iff a\mid{-b}\iff |a|\mid|b| abababab
  2. a ∣ b 且 b ∣ c ⇒ a ∣ c a\mid b且b\mid c\Rightarrow a\mid c abbcac
  3. a ∣ b 且 a ∣ c    ⟺    对 ∀ x , y ∈ Z , 有 a ∣ b x + c y a\mid b 且 a\mid c \iff 对\forall x,y\in Z,有a\mid {bx+cy} abacx,yZ,abx+cy
  4. m ≠ 0 , a ∣ b    ⟺    m a ∣ m b m\neq 0 ,a\mid b \iff ma\mid mb m=0,abmamb
  5. a ∣ b 且 b ∣ a ⇒ b = ± a a\mid b 且 b\mid a \Rarr b=\pm a abbab=±a
  6. b ≠ 0 , a ∣ b ⇒ ∣ a ∣ ≤ ∣ b ∣ b\neq 0,a\mid b \Rarr|a|\le|b| b=0,abab

约数

对于一个数n,其约数定义为能够整除n的数,在整数域内等价于因数

试除法求n的所有约数:

vector<int> get_divisors(int x){
    vector<int> res;
    for (int i = 1; i <= x / i; i ++ )
        if (x % i == 0){
            res.push_back(i);
            if (i != x / i) res.push_back(x / i);
        }
    sort(res.begin(), res.end());
    return res;
}
最大公约数(GCD)

指两个或多个整数中共有的约数中最大的一个 a , b a,b a,b的最大公约数记为 ( a , b ) (a,b) (a,b) gcd ⁡ ( a , b ) \gcd(a,b) gcd(a,b)

特别的 gcd ⁡ ( 0 , a ) = a \gcd(0,a)=a gcd(0,a)=a

最常见使用辗转相除法求gcd

int gcd(int a,int b){
    return b?gcd(b,a%b):a;
}
最小公倍数(LCM)

两个或多个整数最小的公共倍数, a , b a,b a,b的LCM记为 [ a , b ] [a,b] [a,b]

公式: [ a , b ] = a / ( a , b ) ∗ b [a,b]=a/(a,b)*b [a,b]=a/(a,b)b

ll lcm(ll m,ll n){
    ll g1,b;
    g1 = __gcd(m,n);
    b = (m*n) / g1; 
    return b;
}

质数

一个正数p除了 ± 1 , ± p \pm 1,\pm p ±1,±p之外无其他约数,则称p为质数

若a是一个合数,则必有质数p, p ∣ a p\mid a pa

质数的个数是无穷的

判定质数的方法

试除法判质数

适用于数据范围 ≤ 1 0 12 \le10^{12} 1012

试除法的原理就是用 [ 2 , n ] [2,\sqrt{n}] [2,n ]内的所有数试着除n,如果都不能整除,就是素数

时间复杂度 O ( n ) O(\sqrt{n}) O(n )

bool isPrime(int x){
    if(x<2){
        return false;
    }
    for(int i=2;i<=x/i;i++){
        if(x%i==0){
            return false;
        }
    }
    return true;
}

//常数优化 sqrt(x)/3
bool isPrime(int n) {
    if (n == 1) return false;
    if (n == 2 || n == 3) return true;
    if (n % 6 != 1 && n % 6 != 5) return false;
    for (int i = 5, j = n / i; i <= j; i += 6) {
        if (n % i == 0 || n % (i + 2) == 0) {
            return false;
        }
    }
    return true;
}
Miller Rabin素性测试

适用于数据范围 > 1 0 12 >10^{12} >1012时使用

费马素性测试:基于费马小定理

找一个数x,判定 a m − 1 m o d   m ≡ 1 a^{m-1}mod\space m\equiv 1 am1mod m1,如果找到 n n n个数满足判定,就把m认为是质数

正是由于费马小定理无法判断伪质数也叫Carmichael数,所以费马素性测试并不能保证完全正确

二次探测定理:如果 p p p是一个奇素数,且 e ≥ 1 e\ge 1 e1,则方程 x 2 ≡ 1 ( m o d   p e ) x^2\equiv1(mod\space p^e) x21(mod pe)仅有两个解: x = 1 和 x = − 1 x=1和x=-1 x=1x=1 e = 1 e=1 e=1时方程仅有两个解 x = 1 和 x = p − 1 x=1和x=p-1 x=1x=p1,称其为平凡平方根

Miller Rabin算法在费马素性测试基础上通过二次探测定理改进而来

如果一个数满足方程 x 2 ≡ 1 ( m o d   n ) x^2\equiv1(mod\space n) x21(mod n) x x x不等于平凡平方根1或n-1,则称其为非平凡平方根,如果对模n存在1的非平凡平方根,n就是合数

ll mul(ll a, ll b, ll m) {
    return static_cast<__int128_t>(a) * b % m;
}
ll power(ll a, ll b, ll m) {
    ll res = 1 % m;
    for (; b; b >>= 1, a = mul(a, a, m))
        if (b & 1)
            res = mul(res, a, m);
    return res;
}
bool isprime(ll n) {
    if (n < 2)
        return false;
    static constexpr int A[] = {2, 3, 5, 7, 11, 13, 17, 19, 23};
    int s = __builtin_ctzll(n - 1);
    ll d = (n - 1) >> s;
    for (auto a : A) {
        if (a == n)
            return true;
        ll x = power(a, d, n);
        if (x == 1 || x == n - 1)
            continue;
        bool ok = false;
        for (int i = 0; i < s - 1; ++i) {
            x = mul(x, x, n);
            if (x == n - 1) {
                ok = true;
                break;
            }
        }
        if (!ok)
            return false;
    }
    return true;
}

标准分解形式

n = p 1 k 1 p 2 k 2 . . . p n k n n=p_1^{k_1}p_2^{k_2}...p_n^{k_n} n=p1k1p2k2...pnkn { p 1 < p 2 < . . . < p n } \{p_1<p_2<...<p_n\} {p1<p2<...<pn}

p i p_i pi为质数,也为质因数分解形式

算数基本定理:任意一个大于1的整数都可以被分解成若干个质数相乘的形式

  1. n = p 1 a 1 p 2 a 2 . . . p n a n n=p_1^{a_1}p_2^{a_2}...p_n^{a_n} n=p1a1p2a2...pnan

    m = p 1 b 1 p 2 b 2 . . . p n b n m=p_1^{b_1}p_2^{b_2}...p_n^{b_n} m=p1b1p2b2...pnbn

    0 ≤ b i ≤ a i , i = 1 , . . . , k 0\le b_i\le a_i,i=1,...,k 0biai,i=1,...,k,则m是n的正因数

  2. n = p 1 a 1 p 2 a 2 . . . p n a n , a i > 0 , i = 1 , 2 , . . . , k n=p_1^{a_1}p_2^{a_2}...p_n^{a_n},a_i>0,i=1,2,...,k n=p1a1p2a2...pnanai>0,i=1,2,...,k,则n的正因数个数有 ( a 1 + 1 ) ( a 2 + 1 ) . . . ( a k + 1 ) (a_1+1)(a_2+1)...(a_k+1) (a1+1)(a2+1)...(ak+1)

  3. n = p 1 a 1 p 2 a 2 . . . p n a n n=p_1^{a_1}p_2^{a_2}...p_n^{a_n} n=p1a1p2a2...pnan

    m = p 1 b 1 p 2 b 2 . . . p n b n m=p_1^{b_1}p_2^{b_2}...p_n^{b_n} m=p1b1p2b2...pnbn

    ( a , b ) = p 1 γ 1 p 2 γ 2 . . . p n γ n (a,b)=p_1^{\gamma_1}p_2^{\gamma_2}...p_n^{\gamma_n} (a,b)=p1γ1p2γ2...pnγn

    [ a , b ] = p 1 σ 1 p 2 σ 2 . . . p n σ n [a,b]=p_1^{\sigma_1}p_2^{\sigma_2}...p_n^{\sigma_n} [a,b]=p1σ1p2σ2...pnσn

    其中 γ i = m i n ( a i , b i ) , σ i = m a x ( a i , b i ) , i = 1 , 2 , . . . , k \gamma_i=min(a_i,b_i),\sigma_i=max(a_i,b_i),i=1,2,...,k γi=min(ai,bi),σi=max(ai,bi),i=1,2,...,k

  4. 约数之和: ( p 1 0 + p 1 1 + . . . + p 1 k 1 ) ∗ ( p 2 0 + p 2 1 + . . . + p 2 k 2 ) ∗ . . . ∗ ( p n 0 + . . . + p k k n ) (p_1^0+p_1^1+...+p_1^{k_1})*(p_2^0+p_2^1+...+p_2^{k_2})*...*(p_n^0+...+p_k^{k_n}) (p10+p11+...+p1k1)(p20+p21+...+p2k2)...(pn0+...+pkkn)

质因数分解

试除法分解质因数

时间复杂度 O ( n ) O(\sqrt{n}) O(n )

map<int,int> cnt;
void divide(int x){
    for(int i=2;i<=x/i;i++){
        if(x%i==0){
            while(x%i==0){
                x/=i;
                cnt[i]++;
            }
        }
    }
    if(x>1) cnt[x]++;
}
Pollard Rho算法

pollard rho用于求解大数质因子问题,使用Miller Rabin判断质数,原理是生日悖论,了解即可

ll mul(ll a, ll b, ll m) {
    return static_cast<__int128_t>(a) * b % m;
}
ll power(ll a, ll b, ll m) {
    ll res = 1 % m;
    for (; b; b >>= 1, a = mul(a, a, m))
        if (b & 1)
            res = mul(res, a, m);
    return res;
}
bool isprime(ll n) {//Miller Rabin部分
    if (n < 2)
        return false;
    static constexpr int A[] = {2, 3, 5, 7, 11, 13, 17, 19, 23};
    int s = __builtin_ctzll(n - 1);
    ll d = (n - 1) >> s;
    for (auto a : A) {
        if (a == n)
            return true;
        ll x = power(a, d, n);
        if (x == 1 || x == n - 1)
            continue;
        bool ok = false;
        for (int i = 0; i < s - 1; ++i) {
            x = mul(x, x, n);
            if (x == n - 1) {
                ok = true;
                break;
            }
        }
        if (!ok)
            return false;
    }
    return true;
}
std::vector<ll> factorize(ll n) {//pollard rho部分,所有的质因数都会作为vector元素返回
    std::vector<ll> p;
    std::function<void(ll)> f = [&](ll n) {
        if (n <= 10000) {
            for (int i = 2; i * i <= n; ++i)
                for (; n % i == 0; n /= i)
                    p.push_back(i);
            if (n > 1)
                p.push_back(n);
            return;
        }
        if (isprime(n)) {
            p.push_back(n);
            return;
        }
        auto g = [&](ll x) {
            return (mul(x, x, n) + 1) % n;
        };
        ll x0 = 2;
        while (true) {
            ll x = x0;
            ll y = x0;
            ll d = 1;
            ll power = 1, lam = 0;
            ll v = 1;
            while (d == 1) {
                y = g(y);
                ++lam;
                v = mul(v, std::abs(x - y), n);
                if (lam % 127 == 0) {
                    d = std::__gcd(v, n);
                    v = 1;
                }
                if (power == lam) {
                    x = y;
                    power *= 2;
                    lam = 0;
                    d = std::__gcd(v, n);
                    v = 1;
                }
            }
            if (d != n) {
                f(d);
                f(n / d);
                return;
            }
            ++x0;
        }
    };
    f(n);
    std::sort(p.begin(), p.end());
    return p;
}

整除函数

定义

x ∈ R x\in R xR,定义[x]等于不超过x的最大整数,称[x]为取整函数或高斯函数,也称[x]为x的整数部分,{x}为x的小数部分

性质

  1. x = [ x ] + x x=[x]+{x} x=[x]+x

  2. [ x ] ≤ x < [ x ] + 1 , x − 1 < [ x ] ≤ x , 0 ≤ { x } < 1 [x]\le x <[x]+1,x-1<[x]\le x,0\le{\{x\}}<1 [x]x<[x]+1,x1<[x]x,0{x}<1

  3. n ∈ Z , 则 [ n + x ] = n + [ x ] n\in Z,则[n+x]=n+[x] nZ,[n+x]=n+[x]

  4. [ x ] + [ y ] ≤ [ x + y ] , { x } + { y } ≥ { x + y } [x]+[y]\le{[x+y]},\{x\}+\{y\}\ge\{x+y\} [x]+[y][x+y],{x}+{y}{x+y}

  5. 带余除法:设 a , b ∈ Z , b > 0 , 则 a = b [ a b ] + b { a b } , 0 ≤ b { a b } ≤ b − 1 a,b\in Z,b>0,则a=b[\frac{a}{b}]+b\{\frac{a}{b}\},0\le b\{\frac{a}{b}\}\le b-1 a,bZ,b>0,a=b[ba]+b{ba},0b{ba}b1

  6. a , b ∈ Z + , 则 b 的倍数中小于等于 a 的正整数个数为 [ a b ] a,b\in Z_+,则b的倍数中小于等于a的正整数个数为[\frac{a}{b}] a,bZ+,b的倍数中小于等于a的正整数个数为[ba]

  7. 若 x ≤ y , 则 [ x ] ≤ [ y ] 若x\le y,则 [x]\le [y] xy,[x][y]

二元一次不定方程

定义

未知数必须受到某种限制(如整数,正整数,有理数等)的方程,称为不定方程

a , b , c ∈ Z , a b ≠ 0 a,b,c\in Z,ab\neq 0 a,b,cZ,ab=0,称式子 a x + b y = c ax+by=c ax+by=c为关于变量x,y的二元一次不定方程

定理

  1. 设二元一次不定方程 a x + b y = c ( a , b , c ∈ Z , a b ≠ 0 ) ax+by=c(a,b,c\in Z,ab\neq 0) ax+by=c(a,b,cZ,ab=0)

    有一整数解 x = x 0 , y = y 0 , 且 ( a , b ) = d , a = a 1 d , b = b 1 d x=x_0,y=y_0,且(a,b)=d,a=a_1d,b=b_1d x=x0,y=y0,(a,b)=d,a=a1d,b=b1d则此不定方程的一切整数解可以表示为 x = x 0 − b 1 t , y = y 0 − a 1 t , t ∈ Z x=x_0-b_1t,y=y_0-a_1t,t\in Z x=x0b1t,y=y0a1t,tZ

  2. 二元一次不定方程 a x + b y = c ax+by=c ax+by=c有整数解的充要条件是 ( a , b ) ∣ c (a,b)\mid c (a,b)c

  3. 裴蜀定理:二元一次不定方程 a x + b y = c ax+by=c ax+by=c一定存在x,y 使得 a x + b y = ( a , b ) ax+by=(a,b) ax+by=(a,b)

    可以拓展到多元一次不定方程:

    void solve(){
        int n;
        cin>>n;
        vector<int> a(n);
        in(a,n);//输入n个系数
        int sum=0;
        For(i,0,a.size()){
            sum=__gcd(sum,abs(a[i]));//gcd(0,a)=a
        }
        cout<<sum<<"\n";
    }
    

扩展欧几里得(exGCD)

求解二元一次不定方程 a x + b y = ( a , b ) ax+by=(a,b) ax+by=(a,b)的一个特解

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

如何用扩展欧几里得算法求二元一次不定方程 a x + b y = c , g c d ( a , b ) ∣ c ax+by=c,gcd(a,b)\mid c ax+by=c,gcd(a,b)c的解

先用exgcd求出 a x + b y = ( a , b ) ax+by=(a,b) ax+by=(a,b)的一个特解 x 0 , y 0 x_0,y_0 x0,y0,然后然后给每个数乘上 c / g c d ( a , b ) c/gcd(a,b) c/gcd(a,b)即可

通解便是 x = x 0 + b gcd ⁡ ( a , b ) ∗ k , y = y 0 − a gcd ⁡ ( a , b ) ∗ k x=x_0+\frac{b}{\gcd(a,b)}*k,y=y_0-\frac{a}{\gcd(a,b)}*k x=x0+gcd(a,b)bk,y=y0gcd(a,b)ak

使用扩展欧几里得求线性同余方程:设同余方程 a x ≡ b ( m o d   c ) ax\equiv b(mod\space c) axb(mod c)

根据同余定义,我们可以将同余方程化为二元一次不定方程 a x − c y = b ax-cy= b axcy=b,这个时候就可以使用exgcd求出一组 ( a , c ) (a,c) (a,c)的特解了,再乘以 b / gcd ⁡ ( a , c ) b/\gcd(a,c) b/gcd(a,c)就是最后的答案 a n s ans ans,如果结果要求是正数,我们可以使用 ( a n s + c g c d ( a , c ) ) % c g c d ( a , c ) (ans+\frac{c}{gcd(a,c)})\%\frac{c}{gcd(a,c)} (ans+gcd(a,c)c)%gcd(a,c)c的形式获得最小正解,解题时要使b为正数

eg:[P1516 青蛙的约会 - 洛谷](P1516 青蛙的约会 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn))

int exgcd(int a, int b, int &x, int &y) {
    if (!b) {
        x = 1, y = 0;
        return a;
    }
    int g = exgcd(b, a % b, y, x);
    y -= a / b * x;
    return g;
}
void solve(){
    int a,b,m,n,l;
    cin>>a>>b>>m>>n>>l;
    if(n-m<0)swap(a,b),swap(m,n);
    int x,y;
    int g=exgcd((n-m),l,x,y);
    if((a-b)%g){//如果最大公约数不是(a-b)的倍数一定无解
        cout<<"Impossible\n";
    }else{
        cout<<((x*((a-b)/g))%(l/g)+(l/g))%(l/g)<<"\n";//最小正整数解
    }
}

同余

定义

m > 0 m>0 m>0,如果 a , b a,b a,b的差 a − b a-b ab能被m整除,即有q使得 a − b = q m a-b=qm ab=qm ,称a,b关于模m同余,记为 a ≡ b ( m o d   m ) a\equiv{b(mod\space m)} ab(mod m)

e g : 62 ≡ 48 ( m o d   7 ) eg:62\equiv{48(mod\space 7)} eg:6248(mod 7)

性质

  1. 同余具有自反,对称,传递性,同余是等价关系

  2. a ≡ b ( m o d   m ) , c ≡ d ( m o d   m ) , 则 a ± c ≡ b ± d ( m o d   m ) a\equiv {b(mod \space m)},c\equiv{d(mod\space m)},则 a\pm{c}\equiv{b\pm{d}(mod\space m)} ab(mod m),cd(mod m),a±cb±d(mod m)

  3. a ≡ b ( m o d   m ) , c ≡ d ( m o d   m ) , 则 a c ≡ b d ( m o d   m ) a\equiv {b(mod \space m)},c\equiv{d(mod\space m)},则 ac\equiv{bd(mod\space m)} ab(mod m),cd(mod m),acbd(mod m),反之不然

  4. a ≡ b ( m o d   m ) , 且 n ∈ N , 则 a n ≡ b n ( m o d   m ) a\equiv {b(mod \space m)},且n\in N,则 a^n\equiv{b^n(mod\space m)} ab(mod m),nN,anbn(mod m)

  5. a c ≡ b c ( m o d   m ) , 且 c ≠ 0 , 则 a ≡ b ( m o d   m ( c , m ) ) ac\equiv{bc(mod\space m)},且c\neq 0,则a\equiv{b(mod\space{\frac{m}{(c,m)}})} acbc(mod m),c=0,ab(mod (c,m)m)

  6. a ≡ b ( m o d   m ) , m = q n , 则 a ≡ b ( m o d   n ) a\equiv b(mod\space m),m=qn,则a\equiv b(mod\space n) ab(mod m),m=qn,ab(mod n)

  7. a ≡ b ( m o d   m i ) , i = 1 , 2 , 3 , . . . , n , 则 a ≡ b ( m o d   [ m 1 , m 2 , . . . m n ] ) a\equiv b(mod\space m_i),i=1,2,3,...,n,则a\equiv b(mod\space [m_1,m_2,...m_n]) ab(mod mi),i=1,2,3,...,n,ab(mod [m1,m2,...mn])

完全剩余系

如果a,b关于m同余,则a与b属于同一类,否则不属于同一类

这样可以得到m个类,即 M i = { i + k m ∣ k ∈ Z } , i = 0 , 1 , 2 , . . . , m − 1 M_i=\{i+km|k\in Z\},i=0,1,2,...,m-1 Mi={i+kmkZ},i=0,1,2,...,m1,称为模m的剩余类

从每个剩余数中各取一个数作为代表,这样得到的m个数成为模m的一个完全剩余系,也叫完系,比如 { 1 , 2 , . . . , m } \{1,2,...,m\} {1,2,...,m}

当m为奇数时, { 0 , ± 1 , ± 2 , . . . , ± m − 1 2 } \{0,\pm 1,\pm 2,...,\pm \frac{m-1}{2}\} {0,±1,±2,...,±2m1}是一个完系

当m为偶数时, { 0 , ± 1 , ± 2 , . . . , ± m 2 } \{0,\pm 1,\pm 2,...,\pm \frac{m}{2}\} {0,±1,±2,...,±2m}是一个完系

a 1 , a 2 , . . . a m a_1,a_2,...a_m a1,a2,...am中每两个数互不同余,则它们毕分属于模m的m个剩余类,组成一个完系

如果 ( n , m ) = 1 (n,m)=1 (n,m)=1,那么当 a 1 , a 2 , . . . a m a_1,a_2,...a_m a1,a2,...am是模m的完系时, n a 1 + k , n a 2 + k , . . . , n a m + k na_1+k,na_2+k,...,na_m+k na1+k,na2+k,...,nam+k模m互不同余,因此他们也是模m的完系

缩系/既约剩余系

在完全剩余系中,与m互质的元素组成的子集

中国剩余定理(CRT)

求解同余方程的一个解,要求 m 1 , m 2 , . . . m n m_1,m_2,...m_n m1,m2,...mn必须互质,如果不互质就需要使用扩展中国剩余定理exCRT

{ x ≡ a 1 ( m o d   m 1 ) x ≡ a 2 ( m o d   m 2 ) . . . . . . x ≡ a n ( m o d   m n ) \begin{aligned}\left\{\begin{array}{lr}x\equiv{a_1(mod\space m_1)}\\x\equiv a_2(mod\space m_2)\\......\\x\equiv{a_n(mod\space m_n)}\end{array}\right.\end{aligned} xa1(mod m1)xa2(mod m2)......xan(mod mn)

x的解公式: x = a 1 ∗ M 1 ∗ M 1 − 1 + a 2 ∗ M 2 ∗ M 2 − 1 + . . . + a n ∗ M n ∗ M n − 1 x= a_1*M_1*M^{-1}_1+a_2*M_2*M^{-1}_2+...+a_n*M_n*M^{-1}_n x=a1M1M11+a2M2M21+...+anMnMn1

其中, M i = ∏ k = 1 n m k m i M_i=\frac{\prod\limits_{k=1}^nm_k}{m_i} Mi=mik=1nmk M i − 1 = i n v ( M i ) M^{-1}_i=inv(M_i) Mi1=inv(Mi)

费马小定理

定义

多项式展开中 ( x + y ) p = x p + ( p 1 ) x p − 1 y + ( p 2 ) x p − 2 y + . . . + y p (x+y)^p=x^p+\binom{p}{1}x^{p-1}y+\binom{p}{2}x^{p-2}y+...+y^p (x+y)p=xp+(1p)xp1y+(2p)xp2y+...+yp

其中 ( p k ) = p ! k ! ( p − k ) ! \binom{p}{k}=\frac{p!}{k!(p-k)!} (kp)=k!(pk)!p!,当p为质数时,对于满足 1 ≤ k ≤ p − 1 1\le k\le p-1 1kp1的k, p ∤ k ! ( p − k ) ! p\nmid k!(p-k)! pk!(pk)!

p ∣ k ! ( p − k ) ! p ! k ! ( p − k ) ! p|k!(p-k)!\frac{p!}{k!(p-k)!} pk!(pk)!k!(pk)!p!,所以 p ∣ ( p k ) , k = 1 , 2 , . . . , p − 1 p|\binom{p}{k},k=1,2,...,p-1 p(kp),k=1,2,...,p1

从而有 ( x + y ) p ≡ x p + y p ( m o d   p ) (x+y)^p\equiv{x^p+y^p(mod\space p)} (x+y)pxp+yp(mod p)

令x=1,y=1,可得 2 p ≡ 2 ( m o d   p ) 2^p\equiv{2(mod\space p)} 2p2(mod p),令x=2,y=1,可得 3 p ≡ 3 ( m o d   p ) 3^p\equiv{3(mod\space p)} 3p3(mod p),…

因此对于所有 a = 1 , 2 , . . . , p − 1 a=1,2,...,p-1 a=1,2,...,p1,都有 a p ≡ a ( m o d   p ) a^p\equiv a(mod \space p) apa(mod p)

得到费马小定理:对于任意整数a和质数p,都有 a p ≡ a ( m o d   p ) a^p\equiv a(mod \space p) apa(mod p)

gcd ⁡ ( a , p ) = 1 , 则 a p − 1 ≡ 1 ( m o d   p ) \gcd(a,p)=1,则a^{p-1}\equiv 1(mod \space p) gcd(a,p)=1,ap11(mod p)

其逆定理不成立,即使得 a n ≡ a ( m o d   n ) a^n\equiv{a(mod\space n)} ana(mod n)成立的n不一定是质数,能使其成立的合数n称为伪质数

341最小伪质数,1000以下还有561和645是伪质数

威尔逊定理

若p为质数,则 ( p − 1 ) ! ≡ − 1 ( m o d   p ) (p-1)!\equiv{-1(mod \space p)} (p1)!1(mod p)

逆元

a a ′ ≡ 1 ( m o d   p ) aa'\equiv{1(mod\space p)} aa1(mod p) a ′ a' a称为a的逆元

所以从费马小定理可以得出, a ′ ≡ a p − 2 ( m o d   p ) a'\equiv a^{p-2}(mod \space p) aap2(mod p)

逆元可以在模意义下用乘法代替原数除法进行运算,即 a / b ≡ a ∗ i n v   b ( m o d   p ) a/b\equiv a*inv\space b(mod \space p) a/bainv b(mod p)

费马小定理求逆元代码

const int mod = 1e9+7;
int qpow(int a,int b){
    int res=1;
    while(b){
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
int inv(int x){return qpow(x,mod-2);}

但是费马小定理求逆元也有局限性,就是p必须为一个质数,除了费马小定理,我们也可以使用扩展欧几里得求逆元,它要求a与模数p互质即可,p不必须为质数

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

欧拉定理

费马定理阐述的是在质数模下,指数的同余性质,当模是合数时,就要用欧拉定理

欧拉函数

ϕ ( n ) \phi(n) ϕ(n):1到n中与n互质的数的个数

互质: gcd ⁡ ( a , b ) = 1 \gcd(a,b)=1 gcd(a,b)=1

e g : ϕ ( 8 ) = 4   { 1 , 3 , 5 , 7 } eg:\phi(8)=4 \space \{1,3,5,7\} eg:ϕ(8)=4 {1,3,5,7}

求单个数字的欧拉函数:

int phi(int x){
    int res = x;
    for (int i = 2; i <= x / i; i ++ )
        if (x % i == 0){
            res = res / i * (i - 1);
            while (x % i == 0) x /= i;
        }
    if (x > 1) res = res / x * (x - 1);
    return res;
}

引理

  1. n n n为一个质数,则 ϕ ( n ) = n − 1 \phi(n)=n-1 ϕ(n)=n1

  2. n n n为某一个素数p的幂次 p a p^a pa,则 ϕ ( p a ) = ( p − 1 ) ∗ p a − 1 \phi(p^a)=(p-1)*p^{a-1} ϕ(pa)=(p1)pa1

  3. n n n为两个质数 a , b a,b a,b的积,则 ϕ ( a ∗ b ) = ϕ ( a ) ∗ ϕ ( b ) \phi(a*b)=\phi(a)*\phi(b) ϕ(ab)=ϕ(a)ϕ(b)

  4. n = p 1 k 1 p 2 k 2 . . . p n k n n=p_1^{k_1}p_2^{k_2}...p_n^{k_n} n=p1k1p2k2...pnkn { p 1 < p 2 < . . . < p n } \{p_1<p_2<...<p_n\} {p1<p2<...<pn},则 ϕ ( n ) = n ( 1 − 1 p 1 ) ( 1 − 1 p 2 ) . . . ( 1 − 1 p k ) \phi(n)=n(1-\frac{1}{p_1})(1-\frac{1}{p_2})...(1-\frac{1}{p_k}) ϕ(n)=n(1p11)(1p21)...(1pk1)

欧拉定理

设n为正整数,考虑 m o d   n mod\space n mod n的缩系,对于缩系中的任意一个元素a,有 a ϕ ( n ) ≡ 1 ( m o d   n ) a^{\phi(n)}\equiv{1(mod\space n)} aϕ(n)1(mod n)

也就是说,若a与n互质,则 a ϕ ( n ) ≡ 1 ( m o d   n ) a^{\phi(n)}\equiv{1(mod\space n)} aϕ(n)1(mod n)

扩展欧拉定理

x n ≡ { x n ( m o d   m ) x < ϕ ( m ) x n   m o d   ϕ ( m ) + ϕ ( m ) ( m o d   ϕ ( m ) ) x ≥ ϕ ( m ) x^n\equiv\begin{aligned}\left\{\begin{array}{lr}x^n(mod\space m)&x<\phi(m)\\x^{n\space mod \space\phi(m)+\phi(m)}(mod\space \phi (m))&x\geq\phi(m)\end{array}\right.\end{aligned} xn{xn(mod m)xn mod ϕ(m)+ϕ(m)(mod ϕ(m))x<ϕ(m)xϕ(m)

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鸦羽FadingRaven

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值