所求即爲:c++
設 \(\gcd(a,b)=d,a=id,b=jd\),得:git
發現由於 \(\gcd(i,j)=1\),因此 \((i+j)\not \mid ij\),這是由於有:函數
所以得 \((i+j)\mid d\)。原式變爲:spa
最後一步是分別枚舉 \(j\) 和 \(i+j\)。枚舉 \(d,j\) 後,\(\left\lfloor \frac{n}{d^2i} \right\rfloor\) 就爲定值了,而後就能夠數論分塊了。code
大體分析一下複雜度,得總枚舉次數爲:get
後一項爲黎曼函數 \(\zeta(x)\),當 \(x=\frac{3}{2}\) 時,其取值約爲 \(2.6\),所以複雜度爲 \(O(n^{\frac{3}{4}})\)。it
#include<bits/stdc++.h> #define maxn 47350 using namespace std; typedef long long ll; template<typename T> inline void read(T &x) { x=0;char c=getchar();bool flag=false; while(!isdigit(c)){if(c=='-')flag=true;c=getchar();} while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();} if(flag)x=-x; } int n,m,tot; ll ans; int p[maxn],mu[maxn]; bool tag[maxn]; void init() { mu[1]=1; for(int i=2;i<=m;++i) { if(!tag[i]) p[++tot]=i,mu[i]=-1; for(int j=1;j<=tot;++j) { int k=i*p[j]; if(k>m) break; tag[k]=true; if(i%p[j]) mu[k]=mu[i]*mu[p[j]]; else { mu[k]=0; break; } } } } ll calc(ll d) { ll v=0; for(int i=2;i<=m/d;++i) { ll val=n/(d*d*i); if(!val) continue; for(int l=i+1,r;l<=2*i-1;l=r+1) { if(val/l==0) break; r=min(val/(val/l),(ll)2*i-1),v+=val/l*(r-l+1); } } return v; } int main() { read(n),m=sqrt(n),init(); for(int i=1;i<=m;++i) if(mu[i]) ans+=mu[i]*calc(i); printf("%lld",ans); return 0; }