题目大意: 给出 a , b a,b a,b,求有多少对自然数对 ( x , y ) (x,y) (x,y) 满足 y 2 − x 2 = a x + b y^2-x^2=ax+b y2−x2=ax+b。
题解
因为 a , b , x , y a,b,x,y a,b,x,y 都是非负整数,所以有 a x + b ≥ 0 ax+b\geq 0 ax+b≥0,即 y 2 − x 2 ≥ 0 y^2-x^2\geq 0 y2−x2≥0,那么有 y ≥ x y\geq x y≥x。
设 k = y − x k=y-x k=y−x,显然 k k k 也是个非负整数。
则有:
y
2
−
x
2
=
a
x
+
b
(
y
−
x
)
(
y
+
x
)
=
a
x
+
b
k
(
k
+
2
x
)
=
a
x
+
b
k
2
+
2
k
x
=
a
x
+
b
2
k
x
−
a
x
=
b
−
k
2
x
=
b
−
k
2
2
k
−
a
\begin{aligned} y^2-x^2&=ax+b\\ (y-x)(y+x)&=ax+b\\ k(k+2x)&=ax+b\\ k^2+2kx&=ax+b\\ 2kx-ax&=b-k^2\\ x&=\frac {b-k^2} {2k-a} \end{aligned}
y2−x2(y−x)(y+x)k(k+2x)k2+2kx2kx−axx=ax+b=ax+b=ax+b=ax+b=b−k2=2k−ab−k2
考虑大力枚举这个东西。
因为 x x x 是非负整数,所以 b − k 2 b-k^2 b−k2 和 2 k − a 2k-a 2k−a 的正负性要一样。
如果都是正: 那么 k k k 的枚举区间是 ( a 2 , b ] (\frac a 2,\sqrt b] (2a,b]。
如果都是负: 那么 k k k 的枚举区间是 [ b , a 2 ) [\sqrt b,\frac a 2) [b,2a)。
枚举的区间都是 a 2 \frac a 2 2a ~ b \sqrt b b,所以我们只需要判一下他们谁大谁小然后决定出上限下限就好了。
还要注意,下限要向上取整,上限要向下取整,以及 k k k 不能枚举到 a 2 \frac a 2 2a,不然分母部分就是 0 0 0 了。
另外,如果 a 2 = b \frac a 2 =\sqrt b 2a=b,那么有无数组解,因为此时 x = 0 0 x=\frac 0 0 x=00,而 0 0 0 乘以任何数都等于 0 0 0,所以 x x x 可以随便取。
代码如下:
#include <cstdio>
#include <cstring>
#include <cmath>
#define ll long long
ll a,b;
int ans=0;
int main()
{
scanf("%lld %lld",&a,&b);
if(a*a==b*4)return printf("inf"),0;
ll l,r;
if(a/2<(ll)sqrt(b))l=a/2+1,r=sqrt(b)+1;
else
{
l=sqrt(b),r=a/2;
if(l*l<b)l++;
if(r*2<a)r++;
}
for(ll k=l;k<r;k++)
if((b-k*k)%(2*k-a)==0)ans++;
printf("%d",ans);
}