• 欧拉函数相关的题目


    POJ 1284
     
    求原根个数:
      即求 euler(euler(p)) = euler(p-1) 其中p为奇素数
      又有 euler(x) = x*(1-1/p1)*...*(1-1/pk)  其中pk为x的质因数
    #include <cstdio>
    #include <cstring>
    
    int all, p, ans, num[100000];
    bool pd[100000];
    
    int main()
    {
        pd[1] = 1;
        for(int i = 1; i < 100000; i++)
            if(!pd[i])
            {
                num[all++] = i;
                for(int j = i+i; j < 100000; j += i)
                    pd[j] = 1;
            }
        while(scanf("%d", &p) != EOF)
        {
            ans = --p;
            for(int i = 0; i < all && num[i] <= p; i ++)
                if(p%num[i] == 0)
                    ans = ans/num[i]*(num[i]-1);
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code
     
     
    POJ 2407
    求与n互质的个数:
      即求euler(n)
    #include <cstdio>
    #include <cstring>
    
    int all, num[100000], ans, n;
    bool pd[100000];
    
    int main()
    {
        pd[1] = 1;
        for(int i = 1; i <= 100000; i++)
            if(!pd[i])
            {
                num[all++] = i;
                for(int j = i+i; j <= 100000; j += i)
                    pd[j] = 1;
            }
        while(scanf("%d", &n) != EOF)
        {
            if(n == 0) break;
            ans = n;
            for(int i = 0; i < all && num[i] <= n; i ++)
                if(n%num[i] == 0)
                {
                    ans = ans/num[i]*(num[i]-1);
                    while(n%num[i] == 0)
                        n /= num[i];
                }
            if(n != 1)
                ans = ans/n*(n-1);
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code

    POJ 2478

    求解前n项欧拉函数之和

    看到网上一个比较漂亮的求解欧拉函数的方法。

    整个求法其实类似筛法求素数。

    对于任何数 x = 2^k * p 其中p为奇数,以下用phi即那个希腊字符表示欧拉函数

    故 对于k>0 phi[x] = 2^k * ( 1 - 1/2) * phi[p] = 2^(k-1) * phi[p] = 2^(k-1) * p * (1-1/p1) * ... * (1- 1/pn) = x/2 * (1-1/p1) * ... * (1- 1/pn) 其中p1 .. pn 为p的质因子。 故每次筛法求出素数时可以向上进行求解欧拉函数。

        对于k=0 phi[x] = x * (1-1/p1) * ... * (1- 1/pn)

    故有此算法

    可以大致看出 复杂度不差于O(nlgn) 

    #include <cstdio>
    #include <cstring>
    #define MAXN 1000005
    int phi[MAXN], n;
    long long sum[MAXN];
    
    void get_phi()
    {
        phi[1] = 0;
        for(int i = 2; i < MAXN; i++)
            if(i&1)
                phi[i] = i;
            else
                phi[i] = i/2;
        for(int i = 2; i < MAXN; i++)
            if(phi[i] == i) // i为素数
                for(int j = i; j < MAXN; j += i)
                    phi[j] = phi[j]/i*(i-1);
    }
    
    int main()
    {
        get_phi();
        for(int i = 1; i < MAXN; i ++)
            sum[i] = sum[i-1]+phi[i];
        while(scanf("%d", &n) != EOF && n)
            printf("%lld
    ", sum[n]);
        return 0;
    }
    View Code
  • 相关阅读:
    C语言scanf函数转换说明表及其修饰符表
    C语言printf函数转换说明表及其修饰符表
    JAVA中this和super用法
    JAVA构造器,重载与重写
    初步学习JAVA面向对象初步认识及面向对象内存分析图举例说明
    webpack4.0报WARNING in configuration警告
    chrome开发者工具--使用 Network 面板测量您的网站网络性能。
    随笔记录--Array类型
    PXC(percona xtradb cluster)新加节点避免SST的方法
    pt-online-schema-change原理解析
  • 原文地址:https://www.cnblogs.com/Mathics/p/4090117.html
Copyright © 2020-2023  润新知