和HDU上面那个GCD题目非常相似,不过这个需要更多思考。
$\gcd(x,y) =S$ S为素数
$\gcd(\frac{x}{S},\frac{y}{S}) = 1$
题目中没有规定x,y的顺序。我们假定 $y<x$ 即$\frac{x}{S} > \frac{y}{S}$
那么就是通过枚举S求 $\frac{x}{S}$ 的欧拉函数值
因为我们求的是(x,y) 所以(y,x)也是成立的,所以需要欧拉函数值×2。
但是$\frac {x} {t}=1,\frac {y} {t}=1$的情况被计算了两次所以需要-1
#include <cstdio> #include <algorithm> #include <cstring> #define Max 11000000 using namespace std; typedef long long ll; int phi[Max]; int prime[Max],tot; bool isPrime[Max]; ll sum[Max]; void GetPhi(){ memset(isPrime,1,sizeof(isPrime)); phi[1]=1; for(int i=2;i<Max;i++){ if(isPrime[i]){ prime[++tot]=i; phi[i]=i-1; } for(int j=1;j<=tot;j++){ if(i*prime[j]>=Max) break; isPrime[i*prime[j]]=0; if(i%prime[j]==0){ phi[i*prime[j]]=phi[i]*prime[j]; break; } phi[i*prime[j]]=phi[i]*(prime[j]-1); } } } int main(){ int n; GetPhi(); ll ans = 0; scanf("%d",&n); for(int i=1;i<=n;i++) sum[i]=sum[i-1]+phi[i]; for(int i=1;i<=tot;i++){ if(prime[i]>n) break; ans+=2*sum[n/prime[i]]-1; } printf("%lld\n",ans); return 0; }