题目链接:https://oj.neauacm.cn/problem.php?cid=1100&pid=2
简洁版题目:
求 1 a = 1 x + 1 y \displaystyle\frac{1}{a}=\frac{1}{x}+ \frac{1}{y} a1=x1+y1的整数对 { x , y } \{x,y\} {x,y}的数量
1 ≤ a ≤ 1 0 12 1\leq a\leq10^{12} 1≤a≤1012
一、 知识点
- 数论
- 唯一分解定理
- 乘法原理
二、分析
将原式转化为
(
x
−
a
)
(
y
−
a
)
=
a
2
(
x
,
y
≠
0
)
\displaystyle (x-a)(y-a)=a^{2} \quad(x,y\neq 0)
(x−a)(y−a)=a2(x,y=0)
可以发现只需要将
a
2
\displaystyle a^{2}
a2分解为两个整数相乘即可
在这里可以使用唯一分解定理,将所有质因子数加一相乘就是该数的因子数了
得到所有因子数之后乘
2
2
2(因为
x
,
y
x,y
x,y分顺序)再减
1
1
1(减去
a
×
a
=
a
2
a\times a=a^{2}
a×a=a2的情况)
就得到最后的答案了
三、 代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1000005;
bool isprime[maxn];
int prime[maxn],top=0;
void get_prime()
{
for(int i=2;i<=maxn;i++)
isprime[i]=1;
for(int i=2;i<=maxn;i++)
{
if(isprime[i])
{
prime[++top]=i;
for(int j=2*i;j<=maxn;j+=i)
{
isprime[j]=0;
}
}
}
}
int main()
{
get_prime();
int _;
scanf("%d",&_);
while(_--)
{
ll a;
scanf("%lld",&a);
ll sum=1;
for(int i=1;i<=top;i++)
{
if(prime[i]>a)
break;
ll cnt=0;
while(a%(ll)prime[i]==0)
{
cnt++;
a=a/(ll)prime[i];
}
sum*=(2LL*cnt+1);
}
if(a!=1)
sum*=3LL;
printf("%lld\n",sum*2-1);
}
return 0;
}