BZOJ 2818 Gcd
思路:枚举每个质数pi,求出∑phi[n/pi],对phi函数前缀和处理一下。
代码:
#include<bits/stdc++.h> using namespace std; #define ll long long #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) const int N=1e7+5; bool not_prime[N]={false}; int phi[N]; int prime[N]; ll sum[N]; int k,n; void Euler(int n) { phi[1]=1; k=0; for(int i=2;i<=n;i++) { if(!not_prime[i]) { phi[i]=i-1; prime[k++]=i; } for(int j=0;i*prime[j]<=n;j++) { not_prime[i*prime[j]]=true; if(i%prime[j]==0)//根据欧拉函数的性质。 { phi[i*prime[j]]=phi[i]*prime[j]; break; } else phi[i*prime[j]]=phi[i]*phi[prime[j]]; } } } int main() { ios::sync_with_stdio(false); cin.tie(0); int n; cin>>n; Euler(n); sum[1]=0; ll ans=0; for(int i=2;i<=n;i++)sum[i]=sum[i-1]+phi[i]; for(int i=0;i<k;i++)ans+=1+sum[n/prime[i]]*2; cout<<ans<<endl; return 0; }
线性筛速度大约是普通筛法的5倍