hdu 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
 

Author
SmallBeer(CML)
 

Source
杭电ACM集训队训练赛(VII)
 

Recommend
lcy   |   We have carefully selected several similar problems for you:   1164  1787  1211  1222  1397 


欧拉公式求小于n并与n互质的数的个数
 Euler函数表达通式:euler(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…(1-1/pn),其中p1,p2……pn为x的所有质因数,x是不为0的整数。euler(1)=1(唯一和1互质的数就是1本身)。 
     欧拉公式的延伸:一个数的所有质因子之和是euler(n)*n/2。
#include<cstdio>
using namespace std;
#define N 1000001
int euler[N];
/*
int euler(int n)
{ 
     int res=n,a=n;  
     for(int i=2;i*i<=a;i++){  
         if(a%i==0){  
             res=res/i*(i-1);
             while(a%i==0) a/=i;  
         }  
     }  
     if(a>1) res=res/a*(a-1);  
     return res;  
}  
*/
void init()
{
     euler[1]=1;
     for(int i=2;i<N;i++)
       euler[i]=i;
     for(int i=2;i<N;i++)
        if(euler[i]==i)
           for(int j=i;j<N;j+=i)
              euler[j]=euler[j]/i*(i-1);
}
int main()
{
    int T,n;
    init();
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        printf("%d\n",euler[n]);
    }
}



你可能感兴趣的:(hdu 1286找新朋友 (欧拉函数筛法))