【JZOJ4919】神炎皇
Description
神炎皇乌利亚很喜欢数对,他想找到神奇的数对。
对于一个整数对(a,b),若满足a+b<=n且a+b是ab的因子,则成为神奇的数对。请问这样的数对共有多少呢?
Solution
设
gcd(a,b)=d,a′=ad,b′=bd
则有
a′+b′|a′b′d
因为
gcd(a′,b′)=1
,所以
a′+b′
不可能是
a′b′
的因子。
则
a′+b′|d
。
因为
(a′+b′)d≤n
,所以
a′+b′≤n−−√
。
设
k=a′+b′
,那么因为
k2≤n
,所以
k≤nk
。
又因为
k|d
,所以
k≤nk2
。
接下来是求符合
a′,b′
的对数,因为
gcd(a′,b′)=1
,所以
gcd(a′,a′+b′)=1
,然后线性筛法求欧拉函数即可。
Code
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define ll long long
#define N 10000010
using namespace std;
ll pr[N/10],phi[N];
bool bz[N];
void get()
{
int cnt=0;
for(int i=2;i<N;i++)
{
if(!bz[i]) pr[++cnt]=i,phi[i]=i-1;
for(int j=1;j<=cnt && i*pr[j]<N;j++)
{
bz[i*pr[j]]=true;
if(i%pr[j]==0)
{
phi[i*pr[j]]=phi[i]*pr[j];
break;
}
else phi[i*pr[j]]=phi[i]*(pr[j]-1);
}
}
}
int main()
{
freopen("uria.in","r",stdin);
freopen("uria.out","w",stdout);
get();
ll n,ans=0;
scanf("%lld",&n);
for(ll i=2;i*i<=n;i++)
ans+=n/(i*i)*phi[i];
printf("%lld",ans);
}