BIT1055 The Euler function

题意:

给a和b,求

f[a]+f[a+1]+....f[b]

f为对应的欧拉函数值

解法:

线性筛法,因为欧拉函数是积性函数

可用筛法计算欧拉函数值

若p ∤ i,ϕ(p*i)=(p-1)*ϕ(i)
若p|i, ϕ(p*i)=p*ϕ(i)

根据以上两个式子将1到10^6内所有数的欧拉函数值通过筛法算出来

然后用ans数组代表

ans[i]=f[1]+f[2]+...f[ans]

最后输入a和b时,结果就是

ans[b]-ans[a]+f[a]

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
#define MAX 1000100
long long f[MAX];//欧拉函数的值
void init()//筛出MAX以内的所有数的欧拉函数值
{
	memset(f,0,sizeof(f));
	f[1]=1;
	for(long long i=2;i<MAX;i++)
	{
		if(f[i]==0)//i为素数
		{
			f[i]=i-1;
			for(long long j=1;j*i<MAX;j++)
			//若p ∤ i,ϕ(p*i)=(p-1)*ϕ(i)
			//若p|i, ϕ(p*i)=p*ϕ(i)
			//p为素数,i为倍数
			{
				if(j%i==0)
				{
					f[i*j]=i*f[j];
				}
				else
				{
					f[i*j]=(i-1)*f[j];
				}
			}
		}
	}
}
long long ans[MAX];
int main()
{
	init();
	long long a,b;
	ans[1]=f[1];
	for(long long i=2;i<MAX;i++)
	{
		ans[i]=ans[i-1]+f[i];
	}
	while(~scanf("%d %d",&a,&b))
	{
		printf("%lld\n",ans[b]-ans[a]+f[a]);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值