题目传送门
题目大意: 给出
a,b,求有多少对自然数对
(x,y) 满足
y2−x2=ax+b。
题解
因为
a,b,x,y 都是非负整数,所以有
ax+b≥0,即
y2−x2≥0,那么有
y≥x。
设
k=y−x,显然
k 也是个非负整数。
则有:
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 是非负整数,所以
b−k2 和
2k−a 的正负性要一样。
如果都是正: 那么
k 的枚举区间是
(2a,b
]。
如果都是负: 那么
k 的枚举区间是
[b
,2a)。
枚举的区间都是
2a ~
b
,所以我们只需要判一下他们谁大谁小然后决定出上限下限就好了。
还要注意,下限要向上取整,上限要向下取整,以及
k 不能枚举到
2a,不然分母部分就是
0 了。
另外,如果
2a=b
,那么有无数组解,因为此时
x=00,而
0 乘以任何数都等于
0,所以
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);
}