题目描述:
给出n,求出三元组(a,b,c)组数,使得gcd(a,b,c)==1且1/a+1/b==1/c。
题解:
代码:
#include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define N 1500050 ll n,ans; int pri[N],cnt,phi[N],mu[N],sum[N]; bool vis[N]; int hed[N],ct; struct EG{int to,nxt;}e[20*N]; void ae(int f,int t) { e[++ct].to=t; e[ct].nxt=hed[f]; hed[f]=ct; } void get_phi() { int lim = (int)sqrt(2*n); mu[1]=sum[1]=1; for(int i=2;i<=lim;i++) { if(!vis[i]) { pri[++cnt]=i; phi[i]=i-1; mu[i]=-1; } for(int j=1;j<=cnt&&i*pri[j]<=lim;j++) { vis[i*pri[j]]=1; if(i%pri[j]) { phi[i*pri[j]]=phi[i]*phi[pri[j]]; mu[i*pri[j]]=-mu[i]; }else { phi[i*pri[j]]=phi[i]*pri[j]; break; } } sum[i]=sum[i-1]+mu[i]; } } int dfs(int u,int v) { int ret = mu[u]*(v/u); for(int j=hed[u];j;j=e[j].nxt) ret+=mu[e[j].to]*(v/e[j].to); return ret; } int main() { scanf("%lld",&n); get_phi(); int l1 = (int)sqrt(n),l2 = (int)sqrt(2*n); for(int i=1;i<=l2;i++) if(mu[i]) for(int j=2*i;j<=l2;j+=i) ae(j,i); for(int i=1;i<=l1;i++) { ans+=1ll*phi[i]; } for(int i=l1+1;i<=l2;i++) { int cnt=0; int v = n/i; cnt+=dfs(i,v); v = i-(n/i)-1; cnt-=dfs(i,v); ans+=cnt; } printf("%lld ",ans); return 0; }