Problem Description
The Euler function phi is an important kind of function in number theory, (n) represents the amount of the numbers which are smaller than n and coprime to n, and this function has a lot of beautiful characteristics. Here comes a very easy question: suppose you are given a, b, try to calculate (a)+ (a+1)+....+ (b)
Input
There are several test cases. Each line has two integers a, b (2<a<b<3000000).
Output
Output the result of (a)+ (a+1)+....+ (b)
Sample Input
3 100
Sample Output
3042
题意:x属于1到n,把f(x)都加起来(f(x)是从一到n有几个数和n互质)
/*
若N是质数p的k次幂(即N=p^k),φ(n)=p^k-p^(k-1)=(p-1)p^(k-1)。
若m,n互质,φ(mn)=(m-1)(n-1)=φ(m)φ(n)
利用欧拉函数如下性质,可以快速求出欧拉函数的值(a为N的质因素)
若( N%a ==0&&(N/a)%a ==0)则有:E(N)= E(N/a)*a;
若( N%a ==0&&(N/a)%a !=0)则有:E(N)= E(N/a)*(a-1);
*/
#include <stdio.h>
#include <string.h>
#define N 3000300
int prime[N],isprime[N];
int ans[N];
void Is_Prime()//筛素数
{
for(int i=2;i<N;++i)
{
for(int j=i*2;j<N;j+=i)
{
isprime[j]=0;
}
}
}
void get_ans(){
int i,j,cnt=0;
for(i=2;i<N;i++)
{
if(isprime[i])
{
prime[cnt++]=i;//存素数
ans[i]=i-1;
}
for(j=0;j<cnt && i*prime[j]<N;j++)//注意这里,i*prime[j]<N 可换成 prime[j]<=N/i(带等号)
{
if(i%prime[j]==0)
ans[i*prime[j]]=ans[i]*prime[j];
else
ans[i*prime[j]]=ans[i]*(prime[j]-1);
}
}
}
int main()
{
int a,b;
memset(isprime,1,sizeof(isprime));
Is_Prime();
get_ans();
while(~scanf("%d%d",&a,&b))
{
__int64 sum=0;//要用64位的或long long型
for(int i=a; i<=b; ++i)
{
sum+=ans[i];
}
printf("%I64d\n",sum);
}
return 0;
}
方法二: 这个方法应该更好懂
#include <stdio.h>
#include <string.h>
#define size 3000300
int euler[size];
void Init()
{
memset(euler,0,sizeof(euler));
euler[1]=1;
for(int i=2;i<size;i++)
if(!euler[i])//euler[i]为零时要么没处理,要么i就是素数
for(int j=i;j<size;j+=i)
{
if(!euler[j])//当euler[j]为零的时候,j的质因子就只有i了
{
euler[j]=j/i*(i-1);;
}
else euler[j]=euler[j]/i*(i-1);//先进行除法是为了防止中间数据的溢出
}
}
int main()
{
int T;
int N,M;
Init();
//scanf("%d",&T);
while(~scanf("%d%d",&N,&M))
{
;
__int64 sum=0;
for(int i=N;i<=M;++i)
sum+=euler[i];
printf("%I64d\n",sum);
}
return 0;
}