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\)的因数.此时确定一些性质判断方案数是否可行:

  1. 枚举\(i = 2x+a-2y\),i与a同奇偶.
  2. \(j = 2x+a+2y\),\(j\)\(a\)同奇偶。
  3. 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;
}
posted @ 2021-06-13 00:04  acmloser  阅读(31)  评论(0编辑  收藏  举报