zoukankan      html  css  js  c++  java
  • hdoj 1286 找新朋友 (欧拉函数)

    找新朋友

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5518    Accepted Submission(s): 2842

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=1286

    Problem 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
     
    解题思路:
      此题是关于欧拉函数的简单数论题,首先我们先来看看欧拉函数(也称 φ函数):
      
              欧拉函数: 对于给定正整数 n ,少于或等于n的数中与n互质的数的数目。
                若n是质数p的i次幂,φ(n)=p^i - p^(i-1)=(p-1)*p^(i-1) (解题关键),因为除了p的倍数外,其他数都跟n互质。
                设n为正整数,以 φ(n)表示不超过n且与n互素的正整数的个数,称为n的欧拉函数值,这里函数
                  φ:N→N,n→φ(n) 称为欧拉函数。
               欧拉函数是积性函数——若m,n互质,φ(mn)=φ(m)φ(n) [积性函数的形式]。
               特殊性质:当n为奇数时,φ(2n)=φ(n), 证明与上述类似
        
      根据欧拉函数,对于给定的 n ,我们总能找到小于 n 的(当 n 为素数时, 等于 n )素数 p1, p2, ··· , pN, 使得
            n = (p1 ^ a1) * (p2 ^ a2) * ···· * (pN ^ aN);
          所以,
            φ(n)=φ(p1 ^ a1) * φ(p2 ^ a2) * ··· * φ(pN ^ aN)
           所以,
            φ(n) = ((p1 - 1)* p1^(a1 - 1)) * ((p2 - 1)* p2^(a2 - 1)) * ··· * ((pN - 1)* pN^(aN - 1))
         
      
      首先,我们假设与 n 互质的数(小于 n ) 有 n 个, 事实上它有 φ(n) 个, 我们可以寻找 n 与 φ(n) 的关系来求解:
             n / φ(n) = (p1 * p2 * ··· * pN) / ((p1-1) * (p2-1) * ··· *(pN-1))
         所以,
            φ(n) = (n * (p1-1) * (p2-1) * ··· *(pN-1)) / (p1 * p2 * ··· * pN);
          即:
            φ(n) = n * ((p1-1) / p1) * ((p2-1) / p2) * ··· * ((pN-1) / pN);
     
    AC代码:
     1 #include<iostream>
     2 #include<cmath>
     3 
     4 using namespace std;
     5 
     6 int Euler(int n);
     7 
     8 int main()
     9 {
    10     int cn, n, num;
    11     cin >> cn;
    12     while(cn--)
    13     {
    14         cin >> n;
    15         num = Euler(n);
    16         cout << num << endl;
    17     }
    18     return 0;
    19 }
    20 
    21 int Euler(int n)
    22 {
    23     int num, i;
    24     num = n;
    25     for(i = 2; i < (int)sqrt(n*1.0)+1; ++i)
    26     {
    27         if(!(n % i )) {
    28             num = num/i *(i-1);
    29             while(!(n % i))
    30                 n /= i;
    31         }
    32     }
    33     if(n > 1)
    34         num = num/n * (n-1);
    35     return num;
    36 }
      
  • 相关阅读:
    oracle 使用toad界面创建DBLINK
    oracle 批量修改
    blast原理
    Masked genomes/sequence
    HSP
    gapped alignment
    genBlastA
    用blastall进行序列比对
    formatdb
    download文件转为可执行格式
  • 原文地址:https://www.cnblogs.com/Duahanlang/p/3055454.html
Copyright © 2011-2022 走看看