杜教篩入門?
http://blog.csdn.net/popoqqq/article/details/45023331php
1 #include<bits/stdc++.h> 2 #define rint register int 3 #define ll long long 4 #define N 2000001 5 using namespace std; 6 int pri[N>>1],vis[N],cnt,cas,n; 7 ll phi[N],mo[N],p[N],q[N]; 8 void predeal(){ 9 mo[1]=phi[1]=1; 10 for(rint i=2;i<N;++i){ 11 if(!vis[i]){phi[i]=i-1;mo[i]=-1;pri[++cnt]=i;} 12 for(rint j=1;j<=cnt&&pri[j]*i<N;++j){ 13 vis[i*pri[j]]=1; 14 if(i%pri[j]){phi[i*pri[j]]=phi[i]*(pri[j]-1);mo[i*pri[j]]=-mo[i];} 15 else{phi[i*pri[j]]=phi[i]*pri[j];mo[i*pri[j]]=0;break;} 16 } 17 } 18 for(rint i=1;i<N;++i)phi[i]+=phi[i-1],mo[i]+=mo[i-1]; 19 } 20 ll getp(int x){return x<N?phi[x]:p[n/x];} 21 ll getq(int x){return x<N?mo[x]:q[n/x];} 22 void solve(int x){ 23 if(x<N)return;int i,j=1,t=n/x; 24 if(vis[t])return;vis[t]=1; 25 p[t]=(1ll*x+1)*x/2;q[t]=1; 26 while(j<x){ 27 i=j+1;j=x/(x/i);solve(x/i); 28 p[t]-=getp(x/i)*(j-i+1); 29 q[t]-=getq(x/i)*(j-i+1); 30 } 31 } 32 int main(){ 33 scanf("%d",&cas);predeal(); 34 while(cas--){ 35 scanf("%d",&n);memset(vis,0,sizeof(vis)); 36 if(n<N)printf("%lld %lld\n",phi[n],mo[n]); 37 else{solve(n);printf("%lld %lld\n",p[1],q[1]);} 38 } 39 return 0; 40 }