zoukankan      html  css  js  c++  java
  • 欧拉函数、欧拉定理、费马小定理、拓展欧拉定理

    欧拉函数、欧拉定理、费马小定理、拓展欧拉定理

    (1.) 欧拉函数

    (1.1) 定义

    定义不超过 (m) 且与 (m) 互质的正整数个数(phi(m)) ,这个函数称为欧拉函数

    例如, (phi(1)=1, phi(3)=2, phi(10)=4)

    (1.2) 表达式及其证明

    [phi(m)=mprod_{i=1}^{n}(1-frac{1}{p_{i}}) ]

    其中 (p_{i})(m) 的质因子,下面证明这个表达式。

    (1))(m) 为素数,则

    [phi(m)=m-1=m(1-frac{1}{m}) ]

    (2))(m) 为素数幂。即 (m=p^{k}) ,其中 (p) 为素数。考虑所有不大于 (m) 且与 (m) 不互质的正整数,他们可以被列举出来,即 (1cdot p, 2cdot p, 3cdot p, ... p^{k -1}cdot p),共计 (p^{k-1}) 个数,所以

    [phi(m)=phi(p^{k}) = p^{k}-p^{k-1}=p^{alpha}(1-frac{1}{p}) ]

    (3))(m) 为合数,那么

    [m=p_{1}^{k_{1}}cdot p_{2}^{k_{2}}cdot ... p_{n}^{k_{n}} ]

    由于欧拉函数是积性函数,又 (p_{i}^{k_{i}}) 两两互质,所以

    [phi(m)=prod_{i=1}^{n}phi(p_{i}^{k_{i}}) ]

    [phi(m)=prod_{i=1}^{n}p_{i}^{k_{i}}(1-frac{1}{p_{i}}) ]

    [phi(m)=mprod_{i=1}^{n}(1-frac{1}{p_{i}}) ]

    至此,表达式推导完毕

    (1.3) 欧拉函数 (code)

    (1.3.1) 求单个数的欧拉函数

    根据

    [phi(m)=mprod_{i=1}^{n}(1-frac{1}{p_{i}}) ]

    计算

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

    (1.3.2) 线性筛一个范围内的欧拉函数

    我们知道,在欧拉筛中,合数 (n) 被其最小的质因子 (p) 筛去

    (n = n'cdot p)

    (pmid n'),则 (n') 含有 (n) 的所有质因子

    所以

    [phi(n) = pcdot n'cdot prod_{i=1}^{n}(1-frac{1}{p_{i}}) = pcdot phi(n') ]

    (p mid n'),则 ((p, n') = 1),由积性函数性质得到

    [phi(n) = phi(p)cdot phi(n') = (p - 1)cdot phi(n') ]

    int n, prime[N], phi[N], vis[N];
    int Euler_sieve()
    {
        int cnt = 0;//length of prime table
        for(int i = 2; i <= n; ++i)
            vis[i] = 1;
        for(int i = 2; i <= n; ++i){
            if(vis[i]) prime[++cnt] = i, phi[i] = i - 1;//素数的欧拉函数值为 i - 1
            for(int j = 1; j <= cnt && prime[j] * i <= n; ++j){
                vis[prime[j] * i] = 0;
                phi[prime[j] * i] = phi[i] * (prime[j] - 1);
                if(i % prime[j] == 0) {
                    phi[prime[j] * i] = prime[j] * phi[i];
                    break;
                }
            }
        }
        return cnt;
    }
    

    (2.) 欧拉定理

    ((a, m)=1) ,则 (a^{phi(m)}equiv 1 (mod m))

    下证欧拉定理

    设模 (m) 的一个简化剩余系 (P_{1}),其中的元素为

    [p_{i}, i = 1, 2, ... , phi(m) - 1 ]

    我们知道

    [ap_{i}, i = 1, 2, ... , phi(m) - 1 ]

    也构成模 (m) 的一个简化剩余系

    所以

    [prod_{i=1}^{phi(m)}ap_{i}equiv prod_{i=1}^{phi(m)}p_{i} (mod m) ]

    [(a^{phi(m)}-1)prod_{i=1}^{phi(m)}p_{i}equiv 0 (mod m) ]

    由于 (p_{i})(m) 互质,所以

    [(p_{i}, m) = 1 ]

    所以

    [(prod_{i=1}^{phi(m)}p_{i}, m) = 1 ]

    所以

    [a^{phi(m)}-1equiv 0 (mod m) ]

    [a^{phi(m)}equiv 1 (mod m) ]

    至此,定理证明完毕

    (3.) 费马小定理

    ((a, m)=1) ,则 (a^{m-1}equiv 1 (mod m))

    费马小定理其实是欧拉定理的一种特殊情况,即模数 (m) 是素数时的情况

    证明了欧拉定理,也就证明了费马小定理

    (4.) 拓展欧拉定理

    对于 (a, b, m),若满足

    [bgeq phi(m), (a, m) eq 1 ]

    [a^{b}equiv a^{b mod phi(m) + phi(m)} (mod m) ]


    先证明三个引理

    (1.)(m_{1}, m_{2}, ... , m_{k}) 互质,则由 (xequiv y (mod m_{i}), i = 1, 2, ...\, k),可以推出 (xequiv y (mod m_{1}m_{2}...m_{k}))

    (2.)((a, m)=1),则 (a^{b}equiv a^{b mod phi(m)} (mod m))

    (3). 对于素数幂 (p^{k}),满足 (phi(p^{k})geq k, kin mathbb{N})


    先证明引理 (1)

    (m_{1}, m_{2}, ... , m_{k}) 互质

    [(m_{1}, m_{2}, ... , m_{k}) = 1 ]

    [[m_{1}, m_{2}, ... , m_{k}] = m_{1}m_{2}...m_{k} ]

    [xequiv y (mod m_{i}), i = 1, 2, ...\, k ]

    知道 (x - y)(m_{1}, m_{2}, ... , m_{k}) 的公倍数

    所以

    [[m_{1}, m_{2}, ... , m_{k}]mid x - y ]

    所以

    [xequiv y (mod m_{1}m_{2}...m_{k}) ]

    (Q.E.D)


    下证引理 (2)

    [a^{b}=a^{b-b mod phi(m)+b mod phi(m)} ]

    [a^{b}=a^{b-b mod phi(m)}cdot a^{b mod phi(m)} ]

    要证明引理 (2),即证明

    [a^{b-b mod phi(m)}cdot a^{b mod phi(m)}equiv a^{b mod phi(m)} (mod m) ]

    由于

    [(a, m) = 1 ]

    所以

    [(a^{b mod phi(m)}, m) = 1 ]

    所以转化为证明

    [a^{b-b mod phi(m)}equiv 1 (mod m) ]

    由于

    [phi(m)mid b-b mod phi(m) ]

    [b-b mod phi(m) = qcdot phi(m), qin mathbb{Z} ]

    结合欧拉定理

    [a^{phi(m)}equiv 1 (mod m) ]

    由同余性质,将 (q) 个上式相乘即可得到要证明的式子

    (Q.E.D.)


    下证引理 (3)

    [phi(p^{k}) = p^{k} - p^{k - 1} = p^{k - 1}(p - 1) ]

    要证明

    [phi(p^{k})geq k, kin mathbb{N} ]

    即证明

    [p^{k - 1}(p - 1)geq k, kin mathbb{N} ]

    由于 (p -1geq 1),故考虑证明

    [p^{k - 1}geq k, kin mathbb{N} ]

    由于 (p) 是素数,对 (p) 进行放缩,有 (pgeq 2)

    考虑证明 (2^{k - 1}geq k, kin mathbb{N})

    构造数列

    [f(k) = 2^{k - 1} - k, kin mathbb{N} ]

    [f(k + 1) - f(k) = 2^{k - 1} - 1 ]

    (kgeq 1) 时,(f(k + 1) - f(k)geq 0),所以此时数列递增

    取最小值,得到

    [f(k)geq f(1) = 0 ]

    所以

    [2^{k - 1}geq k, kgeq 1 ]

    特判 (k = 0)

    [2^{0 - 1} = frac{1}{2}geq 0 ]

    所以

    [2^{k - 1}geq k, kin mathbb{N} ]

    所以

    [phi(p^{k}) = p^{k - 1}(p - 1)geq p^{k - 1}geq 2^{k - 1}geq k, kin mathbb{N} ]

    所以

    [phi(p^{k})geq k, kin mathbb{N} ]

    (Q.E.D.)


    下证拓展欧拉定理

    (m) 分解,即

    [m = p_{1}^{k_{1}}cdot p_{2}^{k_{2}}cdot ... cdot p_{n}^{k_{n}} ]

    由引理 (1) 知道,若对于每一个 (p_{i})

    都有

    [a^{b}equiv a^{b mod phi(p_{i}^{k_{i}}) + phi(p_{i}^{k_{i}})} (mod p_{i}^{k_{i}}) ]

    则待证命题成立

    分类讨论 ((a, p_{i}^{k_{i}}))

    [(a, p_{i}^{k_{i}}) = 1 ]

    [a^{phi(p_{i}^{k_{i}})}equiv 1 (mod p_{i}^{k_{i}}) ]

    所以

    [a^{b mod phi(p_{i}^{k_{i}}) + phi(p_{i}^{k_{i}})}equiv a^{b mod phi(p_{i}^{k_{i}})} (mod p_{i}^{k_{i}}) ]

    由引理 (2) 知道

    [a^{b}equiv a^{b mod phi(p_{i}^{k_{i}})} (mod p_{i}^{k_{i}}) ]

    所以

    [a^{b}equiv a^{b mod phi(p_{i}^{k_{i}}) + phi(p_{i}^{k_{i}})} (mod p_{i}^{k_{i}}) ]

    [(a, p_{i}^{k_{i}}) eq 1 ]

    [p_{i}mid a_{i} ]

    [a = qcdot p_{i}, qin mathbb{Z} ]

    所以

    [a^{k_{i}}equiv q^{k_{i}}cdot p_{i}^{k_{i}}equiv 0 (mod p_{i}^{k_{i}}) ]

    由于

    [p_{i}^{k_{i}}mid m ]

    所以

    [phi(p_{i}^{k_{i}})mid phi(m) ]

    由引理 (3),结合 (bgeq phi(m)),可以得到不等式

    [bgeq phi(m)geq phi(p_{i}^{k_{i}})geq k_{i} ]

    [a^{b}equiv a^{b - k_{i}}cdot a^{k_{i}}equiv 0 (mod p_{i}^{k_{i}}) ]

    [a^{ phi(p_{i}^{k_{i}})}= a^{ phi(p_{i}^{k_{i}})- k_{i}}cdot a^{k_{i}}equiv 0 (mod p_{i}^{k_{i}}) ]

    所以

    [a^{b}equiv 0 (mod p_{i}^{k_{i}}) ]

    [a^{b mod phi(p_{i}^{k_{i}}) + phi(p_{i}^{k_{i}})}equiv a^{b mod phi(p_{i}^{k_{i}})}cdot a^{ phi(p_{i}^{k_{i}})}equiv 0 (mod p_{i}^{k_{i}}) ]

    所以

    [a^{b}equiv a^{b mod phi(p_{i}^{k_{i}}) + phi(p_{i}^{k_{i}})} (mod p_{i}^{k_{i}}) ]

    综合上述讨论得知,对于每一个 (p_{i}) 都有

    [a^{b}equiv a^{b mod phi(p_{i}^{k_{i}}) + phi(p_{i}^{k_{i}})} (mod p_{i}^{k_{i}}) ]

    所以

    [a^{b}equiv a^{b mod phi(m) + phi(m)} (mod m) ]

    (Q.E.D.)


    综合一下,欧拉定理即为 (a^{b}equiv a^{b mod phi(m) + phi(m)} (mod m))

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int, int>
    #define arrayDebug(a, l, r) for(int i = l; i <= r; ++i) printf("%d%c", a[i], " 
    "[i == r])
    typedef long long LL;
    typedef unsigned long long ULL;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int inf = 0x3f3f3f3f;
    const int DX[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
    const int DY[] = {0, 0, 1, 0, -1, -1, 1, 1, -1};
    const int MOD = 1e9 + 7;
    const int N = 2e7 + 7;
    const double PI = acos(-1);
    const double EPS = 1e-6;
    using namespace std;
    
    inline int read()
    {
        char c = getchar();
        int ans = 0, f = 1;
        while(!isdigit(c)) {if(c == '-') f = -1; c = getchar();}
        while(isdigit(c)) {ans = ans * 10 + c - '0'; c = getchar();}
        return ans * f;
    }
    
    LL qpow(LL a, LL b, LL m)
    {
        if(!a) return 0;
        LL ans = 1;
        while(b) {
            if(b & 1) ans *= a, ans %= m;
            a *= a, a %= m, b >>= 1;
        }
        return ans;
    }
    
    int phi(int m)
    {
        int ans = m;
        for(int i = 2; i * i <= m; ++i) {
            if(m % i == 0) {
                ans -= ans / i;
                while(m % i == 0) m /= i;
            }
        }
        if(m > 1) ans -= ans / m;
        return ans;
    }
    int main()
    {
        int a, m;
        a = read(), m = read();
        int phim = phi(m);
        int b = 0, f = 0;
        for(char ch = getchar(); isdigit(ch); ch = getchar()) {
            b *= 10, b += ch - '0';
            if(b >= phim) f = 1, b %= phim;
        }
        if(f) b += phim; //b < phi(m) 的时候直接快速幂
        printf("%d
    ", qpow(a, b, m));
        return 0;
    }
    
    

    (5.) 欧拉定理、费马小定理应用

    (5.1) 求逆元

    ((a, m) = 1),同余式

    [axequiv 1 (mod m) ]

    有唯一解 (xequiv a^{-1} (mod m))(a^{-1})(a) 在模 (m) 意义下的逆元

    由欧拉定理

    [a^{phi(m)}equiv 1 (mod m) ]

    所以

    [xequiv a^{-1}equiv a^{phi(m) - 1} (mod m) ]

    特殊的,若 (m) 为素数,(phi(m) = m - 1),所以

    [xequiv a^{-1}equiv a^{m-2} (mod m) ]

    根据快速幂,可以在 (O(logm)) 时间求得 (a^{-1})(m) 是模数)

    LL qpow(LL a, LL b, LL m)
    {
        if(!a) return 0;
        LL ans = 1;
        while(b) {
            if(b & 1) ans *= a, ans %= m;
            a *= a, a %= m, b >>= 1;
        }
        return ans;
    }
    LL inv(LL a, LL m)
    {
        return qpow(a, m - 2, m);
    }
    

    (m) 不是素数,则考虑用拓展欧几里得算法求逆元

    int exgcd(int a, int b, int &x, int &y)
    {
        if(!b) {x = 1, y = 0; return a;}
        int r = exgcd(b, a % b, y, x);//y的值被修改为x',x的值被修改为y'
        y -= a / b * x;
        return r;
    }
    int inv(int a, int m)
    {
        int x, y, r;
        r = exgcd(a, m, x, y);
        while(x < 0) x += m;
        return x % m;
    }
    

    (5.2) 用欧拉定理化简模数

    [a^{b}equiv a^{b mod phi(m) + phi(m)} (mod m) ]

    举个栗子

    多组数据,给定 (p),求 (2^{2^{2^{2^{...}}}} mod p)

    (a = 2^{2^{2^{2^{...}}}})

    则问题转化为求

    [a mod p ]

    由欧拉定理

    [2^{2^{2^{2^{...}}}}equiv 2^{a mod phi(p) + phi(p)} (mod p) ]

    继续求解

    [a mod phi(p) ]

    结合欧拉定理

    [2^{2^{2^{2^{...}}}}equiv 2^{a mod phi(phi(p)) + phi(phi(p))} ]

    继续求解

    [a mod phi(phi(p)) ]

    由此可见,这是一个递归求解,然后回溯的过程

    (phi) 的值越来越小,最终变为 (1),此时达到递归终点,返回 (0),然后开始回溯,加上 (phi)...

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int, int>
    #define arrayDebug(a, l, r) for(int i = l; i <= r; ++i) printf("%d%c", a[i], " 
    "[i == r])
    typedef long long LL;
    typedef unsigned long long ULL;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int inf = 0x3f3f3f3f;
    const int DX[] = {0, -1, 0, 1, 0, -1, -1, 1, 1};
    const int DY[] = {0, 0, 1, 0, -1, -1, 1, 1, -1};
    const int MOD = 1e9 + 7;
    const int N = 1e7 + 7;
    const double PI = acos(-1);
    const double EPS = 1e-6;
    using namespace std;
    
    inline int read()
    {
        char c = getchar();
        int ans = 0, f = 1;
        while(!isdigit(c)) {if(c == '-') f = -1; c = getchar();}
        while(isdigit(c)) {ans = ans * 10 + c - '0'; c = getchar();}
        return ans * f;
    }
    
    LL qpow(LL a, LL b, LL m)
    {
        if(!a) return 0;
        LL ans = 1;
        while(b) {
            if(b & 1) ans *= a, ans %= m;
            a *= a, a %= m, b >>= 1;
        }
        return ans;
    }
    
    int n, prime[N], phi[N], vis[N];
    int Euler_sieve(int n = N - 7)
    {
        phi[1] = 1;
        int cnt = 0;//length of prime table
        for(int i = 2; i <= n; ++i){
            if(!vis[i]) prime[++cnt] = i, phi[i] = i - 1;//素数的欧拉函数值为 i - 1
            for(int j = 1; j <= cnt && prime[j] * i <= n; ++j){
                vis[prime[j] * i] = 1;
                phi[prime[j] * i] = phi[i] * (prime[j] - 1);
                if(i % prime[j] == 0) {
                    phi[prime[j] * i] = phi[i] * prime[j];
                    break;
                }
            }
        }
        return cnt;
    }
    
    int t, p;
    int solve(int p)
    {
        if(p == 1) return 0;
        return qpow(2, solve(phi[p]) + phi[p], p);
    }
    int main()
    {
        t = read();
        int l = Euler_sieve();
        while(t--) {
            p = read();
            printf("%d
    ", solve(p));
        }
        return 0;
    }
    
  • 相关阅读:
    python登录csdn并自动评论下载资源脚本
    聊聊C语言的预编译指令include
    ANSI C、ISO C、Standard C联系与区别
    我对在开发板上开发程序的一些理解
    关于CMTS设备的一些备忘
    一个简单的EJB例子
    手动部署EJB于WebLogic
    eclipse+MyEclipse+WebLogic开发简单的EJB
    我对视频“分辨率”的理解以及在电视上显示的理解
    VC win32 static library静态链接库简单示例
  • 原文地址:https://www.cnblogs.com/ChenyangXu/p/12722574.html
Copyright © 2011-2022 走看看