3 100
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; }