P5596 【XR-4】题 笔记

P5596 【XR-4】题

其实这题我昨天没做出来……所以今天写一下笔记
昨天我还信誓旦旦地说这一定是一道黑题\(OTZ\)。果然菜是原罪。

另外吐槽一下科技楼机房频繁停电,昨天写了两小时的树刨和倍增全没了

题目描述

小 X 遇到了一道题:

给定自然数 \(a,b\)求满足下列条件的自然数对 \((x,y)\) 的个数:

\(y^2 - x^2 = ax + b\)

他不会,只好求助于精通数学的你。

如果有无限多个自然数对满足条件,那么你只需要输出 \(inf\) 即可。

输入格式

一行两个整数 \(a,b\)

输出格式

如果个数有限,一行一个整数,表示个数。

如果个数无限,一行一个字符串 \(inf\)

题解

\(y^2 - x^2 = ax + b\)

\(x^2 + ax + b = y^2\)

最朴素的第一想法一定是移项
刚开始想了一下求两函数交点,但是似乎不好搞,而且当时等号右边的方程还写错了
窝太菜了\(QWQ\)

然后正解应该是配一下方(如果我当时没有去想狗屎枚举……

\((x + \frac{1}{2}a)^2 + b - \frac{1}{4}a^2 = y ^ 2\)

这个式子就比较好看了,两个异号平方数,还有一项是常数,一定可以用平方差公式

\((x + \frac{1}{2}a)^2 - y ^ 2 = \frac{1}{4}a^2 - b\)

\((2x + 2y + a) * (2x - 2y + a) = a^2 - 4b\)

接着就可以暴力枚举了???
并不,直接枚举情况有、、多。

又因为题干中说数对\(( x, y) \geqslant 0\),所以\((2x+2y+a)\geqslant0\)

那么我们就可以根据\(a^2 - 4b\)的情况来确定\((2x - 2y +a)\)的正负性,进而加快枚举速度。

\(a^2 - 4b\)大于零枚举时需要判断:

  1. x是否为正整数,即\((2x + 2y + a) + ( 2x - 2y + a) - 2a\) 是否是4的正整数倍;
  2. y是否为正整数,即\((2x + 2y + a) - ( 2x - 2y + a)\) 是否是4的正整数倍;

\(a^2 - 4b\)小于零枚举时需要判断:

  1. x是否为正整数,即\((2x + 2y + a) - ( 2y - 2x - a) - 2a\) 是否是4的正整数倍;
  2. y是否为正整数,即\((2x + 2y + a) + ( 2y - 2x - a)\) 是否是4的正整数倍;

代码如下:

#include<bits/stdc++.h>
using namespace std;
#define rint register int
#define ll long long
ll a, b;   //十年OI一场空,不开longlong见祖宗
int ans;
int main( void ){
    scanf( "%lld%lld", &a, &b );
    //cout << a << b;
    ll delta;
    delta = a * a - 4 * b;
    //cout << temp;
    if( delta == 0 ){
        cout << "inf";
        return 0;
    }
   //下面注意判断正负性,看哪个是i,哪个是j
    if( delta >= 0ll ){
        for( ll i = 1ll; i * i <= delta; i++ ){
            if( delta % i ) continue;
            if( ( delta / i + i - 2 * a ) % 4 != 0 || ( delta / i + i - 2 * a ) < 0 ) continue;
            if( ( delta / i - i ) % 4 != 0 || ( delta / i - i ) < 0 ) continue;
            ans++;
        }
        
    } else {
        delta *= -1;
        for( ll i = 1ll; i * i <= delta; i++ ){
            if( delta % i ) continue;
            if( ( delta / i - i - 2 * a ) % 4 != 0 || ( delta / i - i - 2 * a ) < 0 ) continue;
            if( ( delta / i + i ) % 4 != 0 ) continue;
            ans++;
        }
    }
    printf( "%d", ans );
    return 0;
}

看来数学还是得好好学啊(小声\(BB\)

猜你喜欢

转载自www.cnblogs.com/with6676/p/11715081.html