地址:http://acm.bit.edu.cn/mod/programming/view.php?a=541
给出a和b,求a到b之间的数的欧拉函数值之和。(2<a<b<1000000).
肯定要打表把1000000以内数的欧拉函数都算出来。一个个算显然很慢,所以我们又可以反向思考,利用类似筛法的方法算出所有数的欧拉函数。具体做法:当前i若没有被更新过,说明是素数,将其倍数的欧拉函数值(因为这些数有i这个质因子)全部利用公式更新;最后算出sum[]再用sum[b]-sum[a-1]可以进一步加快速度。
#include<iostream>
using namespace std;
#define N 1000005
__int64 x[N];
int main()
{
int i,j,a,b;
for(i=1;i<N;i++) x[i]=i;
for(i=2;i<N;i+=2) x[i]/=2;
for(i=3;i<N;i+=2)
{
if(x[i]==i) //未被更新过,可知i是素数
{
for(j=i;j<N;j+=i)
{
x[j]=x[j]/i*(i-1);
}
}
}
for(i=1,x[0]=0;i<N;i++) x[i]+=x[i-1];
while(~scanf("%d%d",&a,&b)) printf("%I64d\n",x[b]-x[a-1]);
return 0;
}