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

    对正整数n,欧拉函数是小于n的正整数中与n互质的数的数目(φ(1)=1,φ(2)=1,φ(3)=2 ……)。

    例如φ(8)=4,因为1,3,5,7均和8互质。

    那么,这个定理有什么用呢???

    来看一道题:

    欧拉函数(phi)

    题目描述:对正整数n,n 的欧拉函数(即φ(N))是少于或等于n 的数中与n 互质的数的数目。例如φ(8)=4,因为1,3,5,7 均和8 互质。

    输入

    一行一个整数N。

    输出

    一行一个整数φ(N)

    样例输入

    8

    样例输出

    4

    哈哈哈,一道裸题,那么我们来仔细分析一下每一步:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <cstdlib>
    #define N 10010
    #define zxy(i , a , b) for(int i = a ; i <= b ; i ++)
    #define yxz(i , a , b) for(int i = a ; i >= b ; i ++)
    #define zxyzxy(i , a , b) for(int i = a ; i < b ; i ++)
    #define yxzyxz(i , a , b) for(int i = a ; i > b ; i ++)
    using namespace std;
    typedef long long ll;
    ll n,ans;
    ll read() {
        ll ans = 0;
        char ch = getchar(),last = ' ';
        while(ch < '0' || ch > '9')
            last = ch , ch = getchar();
        while(ch >= '0' && ch <= '9')
            ans = ans * 10 +ch - '0' , ch = getchar();
        if(last == '-')
            ans =- ans;
        return ans;
    }
    void put(ll x) {
        if(x < 0) {
            putchar('-');
            x = -x;
        }
        if(x == 0) {
            putchar('0');
            return;
        }
        int q[100] , nn = 0;
        while(x)
            q[++ nn] = x % 10 , x /= 10;
        while(nn)
            putchar('0' + q[nn]), --nn;
    }
    int main() {
        //freopen("phi.in","r",stdin);
        //freopen("phi.out","w",stdout);
        n = read();
        ans = n;
        for(int i = 2 ; i * i <= n ; i ++)
        {
            if(n % i ==0)
                ans = ans / i * (i - 1);
            while(n % i == 0)
                n /= i;
        }
        if(n > 1)
            ans = ans / n * (n - 1);
        put(ans);
        return 0;
    }

    这里有个欧拉的公式:

     

    即:

     这个就是代码中的:

    ans = ans / i * (i - 1);

    先除后乘是为了防止溢出。

    咱们从头来看这个代码:

    i代表n的素因子。因为在后面的循环操作中,把n都变成了他的最小素因子,所以就可以把这个数的n次幂的数都可以删掉,就可以省时间。

    i循环到根号n的原因是对于一个正整数n来说,在根号n到n的范围内有且只有一个n的素因子。

    为什么呢?用反证法证明一下,如果有两个或两个以上的素因子在这段区间内的话,那么这两个因子的乘积就肯定会大于n,所以假设不成立。

    那么这种循环到根号n的做法是既省码速,又省空间的。

    因此,在最后要添加一个操作,就是把这个n再求一遍素因子个数。

    因为如果假设n分解成的若干个质因数的幂的乘积中的一个单项式特别大的话,那么它就十分接近于n,所以它的指数就肯定是小于2的(上述已证根号n到n只有一个素因子),所以它的指数只能为1,就只要操作一次而不用像上面的用while来维护了。

    最后的ans就是phi(n)的解了。

  • 相关阅读:
    JavaScript可以做嵌入式开发了
    将指定字符串按指定长度进行剪切
    ASP.NET MVC Controller向View传值的几种方式
    SqlServer将数据库中的表复制到另一个数据库
    PAYPAL 支付,sandbox测试的时候遇到异常:请求被中止: 未能创建 SSL/TLS 安全通道,以及解决方法。
    c# ref与out的区别
    浅谈Tuple之C#4.0新特性
    CentOS7系列学习--修改用户密码
    关于页面多个ajax请求阻塞的问题
    关于overflow的学习
  • 原文地址:https://www.cnblogs.com/Zhoier-Zxy/p/8469582.html
Copyright © 2011-2022 走看看