zoukankan      html  css  js  c++  java
  • 找新朋友

    来源

    http://139.196.145.92/contest_show.php?cid=1890#problem/C

    Description
    新年快到了,“猪头帮协会”准备搞一个聚会,已经知道现有会员N人,把会员从1到N编号,其中会长的号码是N号,凡是和会长是老朋友的,那么该会员的号码肯定和N有大于1的公约数,否则都是新朋友,现在会长想知道究竟有几个新朋友?请你编程序帮会长计算出来。
    
    Input
    输入:第一行是测试数据的组数CN(Case number,1<cn<10000),接着有CN行正整数N(1<n<32768),表示会员人数。
    
    Output
    输出:对于每一个N,输出一行新朋友的人数,这样共有CN行输出。
    
    Sample Input
    2
    25608
    24027
    
    Sample Output
    7680
    16016
    
    前置知识:
    1. Elur函数

      对于正整数n,欧拉函数是小于或等于n的正整数中与n互质的数的数目.如:(varphi (8)=4),为1,3,5,7

      性质:

      • 若p为质数,显然(varphi(p)=p-1)
      • (p=a^b(a,b,p in N^*))(a为质数),(varphi(p)=a^b-a^{(b-1)}=(a-1)*a^{(b-1)}),因为一共有(n=a^b)个数,想要获得所有与n互质的数,只需要除去a的倍数即可.这里简单地解释一下(a^{(b-1)}):设有n中有m个a的倍数,则有(ma=a^b => m=a^{(b-1)}).
      • Elur函数是积性函数,即:(varphi(mn)=varphi(m)*varphi(n)(m,n互质))

      (p=a_1^{b_1}*a_2^{b_2}*a_3^{b_3}...(a_i为质数{p,a_i,b_i|p,a_i,b_i in N^*})),由算术基本定理可知,这里的p可以表示所有的正整数.那么,根据以上三条性质可得:

      [varphi(p)=(a_1-1)*(a_2-1)*(a_3-1)...a_1^{(b_1-1)}*a_2^{(b_2-1)}*a_3^{(b_3-1)}... ]

    分析问题:
    1. 显然只要套一下公式即可
    代码:
    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    typedef long long ll;
    
    ll getNum(ll n);
    
    int main()
    {
        ll n,num,ans;
        scanf("%lld",&num);
        while(num--){
            scanf("%lld",&n);
            ans = getNum(n);
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
    ll getNum(ll n) //计算n中的
    {
        ll num=1;
        for(int i=2;i*i<=n;i++){  //相等的时候也需要包含在内,否则出来的时候只加一次
            if(n%i==0){  //这个内外的乘法参考了晚上的代码,很巧妙,没有对于a^(i-1)次做额外的判断
                n/=i;
                num*=(i-1);  //这里乘了a
                while(n%i==0){  //设n=i^a+j,这边乘了a-1次
                    n/=i;
                    num*=i;
                }
            }
        }
        if(n>1){
            num*=n-1;
        }
        return num;
    }
    

    注:

    • 这边的质数i的遍历是从2开始依次向上遍历的,但合数,如:4不会影响到结果,因为n已经被质数2筛过了
    • wa了两发,都是因为i*i<n,因为如果没有包括i*i=n的范围,那么最后的num*=n-1,有时应该是num*=(n-1)*n
  • 相关阅读:
    滚屏到相应位置才加载图片
    cs文件编译成dll文件
    SPAM搜索引擎垃圾技术
    新HTML元素:Canonical Link(权威链接),解决网络复制内容
    Asp.Net 文件操作基类(读取,删除,批量拷贝,删除,写入,获取文件夹大小,文件属性,遍历目录)
    VS2005发布网站项目时整个站点生成为一个自定义名称的dll文件
    301转向代码合集
    区别不同浏览器,CSS hack写法
    教你识别交换购买友情链接里的八种骗局真相!
    C#中Cookies的存取
  • 原文地址:https://www.cnblogs.com/Arno-vc/p/13722545.html
Copyright © 2011-2022 走看看