欧拉函数线性筛

参考博客:https://blog.csdn.net/HandsomeHow/article/details/51325463

定义:欧拉函数是小于n的数中与n互质的数的数目。例如φ(8)=4,因为1,3,5,7均和8互质。

欧拉函数的通式为φ(x)=x (1-1/p1)(1-1/p2)…(1-1/pk):,其中pi表示x的质因数。特别声明,φ(1)=1。

注意:每种质因数只一个。比如12=223那么φ(12)=12*(1-1/2)*(1-1/3)=4。

其中还有比较特殊的几个。

  1. 若p为质数,n=pk ,则φ(n)=pk-pk-1
  2. 如果n是奇数,那么φ(2n)=φ(n)
  3. 如果n是质数,那么,φ(n)=n-1 ,即所有小于n的数都与他互质。
  4. φ(a*b)=φ(a)*φ(b)
  5. 如果i%p==0,那么,φ(i*p)=φ(i)*p;

计算时phi(x)=x(1-1/p1)…(1-1/pi)中的x(1-1/pi)可以转化为x/pi*(pi-1)用来避免小数的产生,同时先除后乘可以避免溢出。

单个欧拉函数

void euler(int n)
{
    for (int i=1;i<=n;i++) phi[i]=i;
    for (int i=2;i<=n;i++)
    {
        if (phi[i]==i)//这代表i是质数
        {
            for (int j=i;j<=n;j+=i)
            {
                phi[j]=phi[j]/i*(i-1);//把i的倍数更新掉
            }
        }
    }
}

线性筛
思想:保证每个合数只会被他的最小之质因子筛去。

void euler(int n)
{
	phi[1]=1;//1要特判 
	for (int i=2;i<=n;i++)
	{
		if (flag[i]==0)//这代表i是质数 
		{
			prime[++num]=i;
			phi[i]=i-1;
		}
		for (int j=1;j<=num&&prime[j]*i<=n;j++)//经典的欧拉筛写法 
		{
			flag[i*prime[j]]=1;//先把这个合数标记掉 
			if (i%prime[j]==0)
			{
				phi[i*prime[j]]=phi[i]*prime[j];//若prime[j]是i的质因子,则根据计算公式,i已经包括i*prime[j]的所有质因子 
				break;//经典欧拉筛的核心语句,这样能保证每个数只会被自己最小的因子筛掉一次 
			}
			else phi[i*prime[j]]=phi[i]*phi[prime[j]];//利用了欧拉函数是个积性函数的性质 
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值