[bzoj 2818]欧拉函数
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2818
枚举最大公约数,对于每一个质数p,只需要求出1<=x,y<=(n/p)范围内gcd(x,y)=1的对数,而这个对数就是类似欧拉函数的一个前缀和。
#include<cstdio> #include<cstring> using namespace std; const int maxn=10000005; bool check[maxn]; int prime[maxn]; long long phi[maxn]; long long prephi[maxn]; void getPrime() { int N=10000000; memset(check,false,sizeof(check)); prime[0]=0; phi[1]=1; for (int i=2;i<=N;i++) { if (!check[i]) { prime[++prime[0]]=i; phi[i]=i-1; } for (int j=1;j<=prime[0];j++) { if (i*prime[j]>N) break; check[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]*(prime[j]-1); } } } prephi[1]=phi[1]; for (int i=2;i<=N;i++) prephi[i]=prephi[i-1]+2ll*phi[i]; } int main() { getPrime(); int n; scanf("%d",&n); long long ans=0; for (int i=1;i<=prime[0];i++) { if (prime[i]>n) break; int r=n/prime[i]; ans+=prephi[r]; } printf("%lld\n",ans); return 0; }