0818-线性筛欧拉函数

【欧拉函数】在数论,对正整数n,欧拉函数是小于或等于n的正整数中与n互质的数的数目(φ(1)=1)。

【三性质】

  1. 如果i是质数,那么phi[i]=i-1;
  2. 如果a mod b==0&&b是质数,那么phi[a*b]=phi[a]*b
  3. 如果a mod b!=0&&b是质数,(也就是说a,b互质),那么phi[a*b]=phi[a]*phi[b]

【证明】

蒟蒻表示说不清楚,大家自行百度

然而虽然不知道怎么证,但我们可以就用这三个性质把欧拉函数筛出来

【代码】

/*
特性 :
1.若a为质数,phi[a]=a-1;
2.若a为质数,b mod a=0,phi[a*b]=phi[b]*a
3.若a,b互质,phi[a*b]=phi[a]*phi[b](当a为质数时,if b mod a!=0 ,phi[a*b]=phi[a]*phi[b])
*/
int m[n],phi[n],p[n],nump;
//m[i]标记i是否为素数,0为素数,1不为素数;p是存放素数的数组;nump是当前素数个数;phi[i]为欧拉函数
int make()
{
    phi[1]=1;
    for (int i=2;i<=n;i++)
    {
        if (!m[i])//i为素
		数
        {
            p[++nump]=i;//将i加入素数数组p中
            phi[i]=i-1;//因为i是素数,由特性得知    
        }    
        for (int j=1;j<=nump&&p[j]*i<n;j++)  //用当前已的到的素数数组p筛,筛去p[j]*i
        {
            m[p[j]*i]=1;//可以确定i*p[j]不是素数 
            if (i%p[j]==0) //看p[j]是否是i的约数,因为素数p[j],等于判断i和p[j]是否互质 
            {
                phi[p[j]*i]=phi[i]*p[j]; //特性2
                break;
            }
            else phi[p[j]*i]=phi[i]*(p[j]-1); //互质,特性3其,p[j]-1就是phi[p[j]]   
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_42557561/article/details/81812805
今日推荐