P5596 【XR-4】题
原题链接
考察:思维
思路:
神仙题.想了半天还以为和一元二次方程的\(b^2-4ac\)有关系,结果没多大关系(.),或者可能是本蒟蒻没想到
一般是将两个未知量划到左右两边个一边,枚举其中一个来确定方案数.
\[y^2-x^2 = ax+b
\]
\[y^2 = x^2+ax+b
\]
\[4y^2 = 4x^2+4ax+4b
\]
\[4y^2-4b+a^2 = (2x+a)^2
\]
如果枚举x范围还是太大了,因为没有明确的上界,再改变式子就是:
\[a^2-4b = (2x+a)^2-4y^2 = (2x+a-2y)(2x+a+2y)
\]
这样就是枚举\(a^2-4b\)的因数.此时确定一些性质判断方案数是否可行:
- 枚举\(i = 2x+a-2y\),i与a同奇偶.
- \(j = 2x+a+2y\),\(j\)与\(a\)同奇偶。
- x>=0,y>=0,2x+a>=0,由此解方程,求得x,y表达式.
但是还是会超时,此时需要一些优化,可以发现i是与a同奇偶的,所以只枚举与\(a\)同奇偶的数即可.
Code
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
LL a,b;
void GetDivide(LL n)
{
LL ans = 0,m = abs(n);
int sta = (a%2?1:2);
for(LL i=sta;i<= m/i;i+=2)
{
if(n%i==0)
{
LL v = abs(n/i);
LL u = i;
if(n<0) u = -u;
if((u&1)!=(v&1)) continue;
if(v-u<0) break;
if((v-u)%4) continue;
if(u+v<0||(u+v)%2) continue;
LL z = (u+v>>1)-a;
if(z&1||z<0) continue;
ans++;
}
}
printf("%lld\n",ans);
}
int main()
{
scanf("%lld%lld",&a,&b);
if(a*a==4*b) {puts("inf");return 0;}
LL t = a*a-(b<<2);
GetDivide(t);
return 0;
}