zoukankan      html  css  js  c++  java
  • 欧拉函数详解

    欧拉函数

    我们用$phi(n)$表示欧拉函数

    定义:$phi(n)$表示对于整数$n$,小于等于$n$中与$n$互质的数的个数

    性质

    1.$phi(n)$为积性函数

    证明:

    此处证明需要用到下面计算方法1中的内容,建议先看后面再回过头来看这里

    假设存在$p,q$,且$p*q=n$

    将$n,p,q$进行质因数分解

    $n=a_1^{p_1}*a_2^{p_2}...*a_k^{p_k}$

    $p=a_1^{p_1}*a_2^{p_2}...*a_m^{p_m}$

    $q=a_{m+1}^{p_{m+1}}*a_{m+2}^{m+2}...*a_k^{p_k}$

    那么

    $varphi left( n ight) =nprod ^{k}_{i=1}left( 1-dfrac {1}{p_{i}} ight)$

    $varphi left( a ight) =aprod ^{m}_{i=1}left( 1-dfrac {1}{p_{i}} ight)$

    $varphi left( b ight) =bprod ^{k}_{i=m+1}left( 1-dfrac {1}{p_{i}} ight)$

    因为$n=a*b$

    显然

    $varphi left( n ight) =varphi left( a ight) varphi left( b ight)$

    这种方法也是常见的证明一个函数是积性函数的方法

     

    2.$sum_{d|n}phi(d)=n$

    3.$1$到$n$中与$n$互质的数的和为$n*dfrac{phi(n)}{2}(n>1)$

    证明:若$gcd(n, i) = 1$,那么$gcd(n, n - i) = 1$

    因此与$n$互质的数都是成对出现的。且每一对的和都为$n$

    这样最终答案为$n * frac{phi(n)}{2}$

    4. $a^{phi(n)} equiv 1 pmod n$

    计算方法

    $sqrt(n)$计算单值欧拉函数

    假设我们需要计算$phi(n)$

    分情况讨论

    1.当$n=1$时

    很明显,答案为$1$

    2.当$n$为质数时

    根据素数的定义,答案为$n-1$

    (仅有$n$与$n$不互质)

    3.当$n$为合数时

    我们已经知道了$n$为素数的情况

    不妨对$n$进行质因数分解

    设$n=a_1^{p_1}*a_2^{p_2}...*a_k^{p_k}$

    假设$k=1$

    那么$phi(p^k)=p^k-p^{k-1}$

    证明:

    考虑容斥,与一个数互素的数的个数就是这个数减去与它不互素的数的个数

    因为$p$是素数,所以在$p^k$中与其不互素的数为$1*p$,$2*p$....$p^{k-1}*p$,有$p^{k-1}$个

    得证

    当$k eq 1$时

    $$phi(n)$$

    $$=varphi left( a^{p_{1}}_{1}a^{p_{2}ldots }_{2}a^{Pk}_{k} ight)$$

    $$=prod ^{k}_{i=1}a^{P_i}-a^{P_{i}-1}_{i}$$

    $$=prod ^{k}_{i=1}a^{Pi}_{i}(1-dfrac {1}{p_{i}})$$

    $$=n*prod ^{k}_{i=1}(1-dfrac {1}{p_{i}})$$

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int MAXN = 1e7 + 10;
    int p, ans = 1, N;
    void GetPhi() {
        for(int i = 2; i * i <= p; i++) {
            if(p % i == 0) {
                int now = i - 1; p /= i;
                while(p % i == 0) now = now * i, p /= i;
                ans = ans * now;
            }
        }
        if(p != 1) ans *= (p - 1); 
    }
    int main() {
        cin >> p; N = p;
        GetPhi();
        cout << ans;
        return 0;
    }

    线性筛

    因为欧拉函数是积性函数

    因此可以使用线性筛法

    性质1

    若$p$为素数,则$varphi left( p ight) =p-1$

    证明:

    在$1-p$中,只有$(p,p) eq1$

    性质2

    若$i mod p eq  0$,且$p$为素数

    则$varphi left( i*p ight) =varphi left( i ight) *varphi left( p ight)$

    $=varphi left( iast p ight) =varphi left( i ight) ast left( p-1 ight)$

    这一步同时利用了性质1和欧拉函数的积性

    性质3

    若$i mod p = 0$,且$p$为素数,

    则$varphi left( iast p ight) =varphi left( i ight) ast p$

    证明:

    没怎么看懂,丢一个链接

    http://blog.csdn.net/Lytning/article/details/24432651

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN = 3e5 + 10;
    void GetPhi(int N) {
        static int phi[MAXN], vis[MAXN], prime[MAXN], tot = 0;
        for(int i = 2; i <= N; i++) {
            if(!vis[i]) prime[++tot] = i, phi[i] = i - 1;
            for(int j = 1; j <= tot && i * prime[j] <= N; j++) {
                vis[i * prime[j]] = 1;
                if(!(i % prime[j])) {phi[i * prime[j]] = phi[i] * prime[j]; break;}
                else phi[i * prime[j]] = phi[i] * (prime[j] - 1);
            }
        }
        while(cin >> N) cout << phi[N] << endl;
    }
    int main() {
        GetPhi(100);
        return 0;
    }

    例题

    放几道水题

    http://poj.org/problem?id=2407

    题解

    http://poj.org/problem?id=2478

    题解

    https://www.luogu.org/problemnew/show/P2158

    题解

    参考资料

    数论学习笔记 欧拉函数 (一些性质和运用)内置杜教筛

  • 相关阅读:
    Something I know about WebDynpro
    Details about support package implementation
    CRM Middleware Performance Topics
    Way to configure the logon navigaion layouts via Business Roles in CRM
    DOM 常用节点类型和方法
    第一届 xdef 会议日程
    去除百度音乐盒广告的chrome插件 持续更新
    从人人网抓取高校数据信息,包括,省份 高校 院系 (提供最终SQL文件下载)
    PHP 与 JSON
    解决HTTPS 发送请求走socket问题
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/8215259.html
Copyright © 2011-2022 走看看