欧拉函数hdu——————1286

现在先来解释下欧拉函数的的定义:
    就是  正整数n里  小于N且与N互质(gcd为1)的数。
(度娘:在数论,对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目。此函数以其首名研究者欧拉命名,它又称为Euler's
totient function、φ函数、欧拉商数等。 例如φ(8)=4,因为1,3,5,7均和8互质。)
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
 题解:
很显然这是一道欧拉函数题
 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。
那么根据定义模板就是
int euler(int n){ //返回euler(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; 

C++版

/*线性筛O(n)时间复杂度内筛出maxn内欧拉函数值*/
int m[maxn],phi[maxn],p[maxn],pt;//m[i]是i的最小素因数,p是素数,pt是素数个数

int make()
{
    phi[1]=1;
    int N=maxn;
    int k;
phi[1]=1;
    for(int i=2;i<N;i++)
    {
        if(!m[i])//i是素数
            p[pt++]=m[i]=i,phi[i]=i-1;
        for(int j=0;j<pt&&(k=p[j]*i)<N;j++)
        {
            m[k]=p[j];
            if(m[i]==p[j])//为了保证以后的数不被再筛,要break
            {
                phi[k]=phi[i]*p[j];
/*这里的phi[k]与phi[i]后面的∏(p[i]-1)/p[i]都一样(m[i]==p[j])只差一个p[j],就可以保证∏(p[i]-1)/p[i]前面也一样了*/
                break;    
            }
            else
                phi[k]=phi[i]*(p[j]-1);//积性函数性质,f(i*k)=f(i)*f(k)
        }
    }
}


posted on 2015-05-21 19:55  AC_WQYYY  阅读(402)  评论(0编辑  收藏  举报

导航