link
给出 n,统计满足下面条件的数对 (a,b) 的个数:
- 1≤a<b≤n
- a+b ∣ a×b
i,j∑[i+j ∣ ij][1≤i<j≤n]=i,j,d,s,t∑[d=gcd(i,j)][i=sd][j=td][1≤sd<td≤n][d(s+t) ∣ d2st][s⊥t]
注意到 [d(s+t) ∣ d2st] 可以化为 [s+t ∣ dst],而 s⊥t,故 s+t∤st,所以可以化为 [s+t ∣ d]。
=s,t,d∑[1≤sd<td≤n][s+t ∣ d][s⊥t]=s,t,d,k∑[d=k(s+t)][s⊥t][1≤sk(s+t)<tk(s+t)≤n][k≥1]=s,t,k∑[s⊥t][k∈[1,t(s+t)n]][s<t]=s,t∑⌊t(s+t)n⌋[s⊥t][s<t]=s,t,k∑⌊t(s+t)n⌋[k ∣ s][k ∣ t][s<t]μ(k)
换成上下界的形式
t=1∑ns=1∑t−1k ∣gcd(s,t)∑⌊t(s+t)n⌋μ(k)=k=1∑nμ(k)t=1∑⌊kn⌋s=1∑t−1⌊k2t(s+t)n⌋
注意到 k2 和 t2 应小于等于 n,否则后面的式子变为 0。
=k=1∑nμ(k)t=2∑kns=t+1∑2t−1⌊s⌊k2tn⌋⌋
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=sqrt(3e7)+555500;
int n,mu[N],ans,a[N],cnt,pri[N],m;
void init()
{
m=sqrt(n);mu[1]=1;
for(int i=2;i<=m;i++)
{
if(!a[i])pri[++cnt]=i,mu[i]=-1;
for(int j=1;j<=cnt&&pri[j]*i<=m;j++)
{
a[i*pri[j]]=1;
if(i%pri[j]==0)break;
mu[i*pri[j]]=-mu[i];
}
}
}
int find(int x,int L,int R)
{
// cout<<x<<' '<<L<<' '<<R<<' ';
int ans=0;R=min(R,x);
for(int i=L;i<=R;i++)
{
int val=x/i,r=min(R,x/val);
ans+=(r-i+1)*val;
i=r;
}
// cout<<ans<<'\n';
return ans;
}
main()
{
cin>>n;init();
for(int k=1;k<=m;k++)if(mu[k])
{
// cout<<k<<' '<<mu[k]<<'\n';
for(int t=2;t<=m/k;t++)
{
ans+=find(n/(k*k*t),t+1,2*t-1)*mu[k];
}
}
cout<<ans;
}