P9231 题解

· · 题解

一道比较简单的数学题。

首先我们来看题目中的 x=y^2-z^2,由平方差公式可得 x=(y+z)(y-z),因为 yz 都必须是整数,所以题目中每个符合条件的 x 就必须满足它能分解成两个差是偶数的因数相乘,在此情况下令其中较小的因数为 l,较大的因数为 rmid=\frac{(l+r)}{2}k=r-mid=mid-l,则 x 必定可以分成形如 (mid-k)(mid+k) 的形式,很显然对于任意的奇数 a 都满足以上条件,因为可以使 l=1r=a,这时 lr 都是奇数且差是偶数,符合条件;当 a 为奇数时,可以分为两类:一类是 x 能分解成 2\times 2k(其中 k 是整数)的形式的数,这类数也符合条件,因为 22k 都一定是偶数,那么它们的差也必定是偶数;另一类数必定不符合条件,因为两个数相乘为偶数时只有两种情况,要么其中有一个数是偶数,要么两个数都是偶数,第二种情况又必定能分解成 2\times 2k(其中 k 是整数)的形式,已经在前面判断过了,所以剩下来的数只可能分解成一个奇数乘以一个偶数的形式,而我们知道奇数减去偶数是无论如何也不可能是偶数的,因此剩下来的数全都不符合条件。

因此,我们只需要计算 1r 中有多少个符合条件的数,再把它减去 1l-1 中符合条件的数的数量即可。

参考代码如下:

#include<bits/stdc++.h>
using namespace std;
inline int read(){
    int n=0;
    char c=getchar();
    while(c<'0' || c>'9') c=getchar();
    while(c>='0' && c<='9'){
        n=(n<<3)+(n<<1)+(c^48);
        c=getchar();
    }
    return n;
}
int main(){
    int l=read()-1,r=read();
    printf("%d",(r+1)/2+(r/2)/2-((l+1)/2+(l/2)/2));
    return 0;
}