欧拉函数~求互质对数

在数论,对正整数n,欧拉函数是求小于或等于n的数中与n互质的数的数目。
φ函数的值  通式:φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn),其中p1, p2……pn为x的所有质因数,x是不为0的整数。
  φ(1)=1(唯一和1互质的数(小于等于1)就是1本身)。
 (注意:每种质因数只一个。比如12=2*2*3 那么φ(12)=12*(1-1/2)*(1-1/3)=4
 若n是质数p的k次幂,
φ(n)=p^k-p^(k-1)=(p-1)p^(k-1),
因为除了p的倍数外,其他数都跟n互质。
设n为正整数,以 φ(n)表示不超过n且与n互素的正整数的个数,称为n的欧拉函数值。
 
求区间[1,n]内 与 x互质的数的个数。
例如:X的素数因子为{ p1, p2, p3 } ,  则[1,n]内与x不互质的数有{ n/p1,  n/p2,  n/p3, n/(p1*p2), n/(p1*p3), n/(p2*p3), n/(p1*p2*p3) }这其中有亢余项。
运用容斥得:与x不互质的数的个数 
{ n/p1 + n/p2 + n/p3 - n/(p1*p2) - n/(p1*p3) - n/(p2*p3) +  n/(p1*p2*p3) }
分母个数偶减奇加
 
void init()    //求1000以内互质的数的对数
{
    int i, j;
    memset(s, 0, sizeof(s));
    memset(sum, 0, sizeof(sum));
    s[1]=sum[1]=1;
    for(i=2; i<=1000; i++)
    {
        if(!s[i])
            for(j=i; j<=1000; j+=i)
            {
                if(!s[j]) s[j]=j;
                s[j]=s[j]*(i-1)/i; //欧拉公式
            }
        sum[i]= sum[i-1]+s[i]; //累计连和
    }
}
int huzhi(int n)   //单独求n在区间[1,n]内互质的个数
{
    int m=(int)sqrt(n+0.5);
    int ans=n, i;
    for(i=2; i<=m; i++)
        if(n%i==0)  //这个确定i是素数
        {
            ans=ans*(i-1)/i; //欧拉公式
            while(n%i==0)  //这里保证n能够整除的数肯定为素数(所有的合数都能写成几个素数的积)
                n/=i;
        }
    if(n>1) ans=ans*(n-1)/n;
    return ans;
}

 

posted @ 2015-09-22 15:57  马晨  阅读(2629)  评论(0)    收藏  举报