题目求φ(a)+φ(a+1)+...+φ(b-1)+φ(b)。
用欧拉筛选法O(n)计算出n以内的φ值,存个前缀和即可。
- φ(p)=p-1(p是质数),小于这个质数且与其互质的个数就是p-1;
- φ(p*a)=(p-1)*φ(a)(p是质数且p不能整除a),因为欧拉函数是积性函数,φ(p*a)=φ(p)*φ(a);
- φ(p*a)=p*φ(a)(p是质数且p|a),不知怎么理解。。
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 #define MAXN 3000000 5 long long phi[MAXN]; 6 int prime[MAXN]; 7 bool vis[MAXN]; 8 void euler(){ 9 phi[1]=1; 10 int tot=0; 11 for(long long i=2; i<MAXN; ++i){ 12 if(!vis[i]){ 13 prime[tot++]=i; 14 phi[i]=i-1; 15 } 16 for(int j=0; j<tot; ++j){ 17 if(i*prime[j]>MAXN) break; 18 vis[i*prime[j]]=1; 19 if(i%prime[j]==0){ 20 phi[i*prime[j]]=phi[i]*prime[j]; 21 break; 22 }else{ 23 phi[i*prime[j]]=phi[i]*(prime[j]-1); 24 } 25 } 26 } 27 } 28 int main(){ 29 euler(); 30 for(int i=2; i<MAXN; ++i) phi[i]+=phi[i-1]; 31 int a,b; 32 while(~scanf("%d%d",&a,&b)){ 33 printf("%lld ",phi[b]-phi[a-1]); 34 } 35 return 0; 36 }