转化一下题目,即是求$1$到$n$中对于某个素数$pri$使得$gcd(x*pri,y*pri)=pri$的$(x,y)$的数目
这样一来就可以考虑每个质数$pri$对答案的贡献,即为$1$到$\frac{n}{pri}$中互质对的个数。设$x<y$则$x$有$φ(y)$个取值使$x,y$互质,因为有序就乘上一个$2$。对$φ$做前缀和,每次去掉$(1,1)$的重即可
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=1e7+7,P=1e6+6; 6 int pri[P]; 7 bool npr[N]; 8 long long phi[N]; 9 long long n,cnt,ans; 10 void prework(int maxx) 11 { 12 phi[1]=1,npr[1]=true; 13 for(int i=2;i<=maxx;i++) 14 { 15 if(!npr[i]) pri[++cnt]=i,phi[i]=i-1; 16 for(int j=1;j<=cnt&&i*pri[j]<=maxx;j++) 17 { 18 npr[i*pri[j]]=true; 19 phi[i*pri[j]]=phi[i]*pri[j]; 20 if(i%pri[j]) phi[i*pri[j]]-=phi[i]; else break; 21 } 22 } 23 } 24 int main () 25 { 26 scanf("%lld",&n),prework(n); 27 for(int i=1;i<=n;i++) phi[i]+=phi[i-1]; 28 for(int i=1;i<=cnt;i++) ans+=2*phi[n/pri[i]]-1; 29 printf("%lld",ans); 30 return 0; 31 }