所求即为: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; }