#P1305. “异或”新手教程与实践

“异或”新手教程与实践

“异或”新手教程与实践

时间限制:1s

空间限制:256MB

题目背景

以下内容为异或运算的简单介绍,如果已了解可以跳过。


异或(xor)是一个数学运算符。它应用于逻辑运算。异或的数学符号为“⊕”,计算机符号为“xor”。其运算法则为:

如果a、b两个值不相同,则异或结果为 11 。如果a、b两个值相同,异或结果为 00

异或也叫半加运算,其运算法则相当于不带进位的二进制加法:二进制下用1表示真,0表示假,则异或的运算法则为:0⊕0=0,1⊕0=1,0⊕1=1,1⊕1=0(同为0,异为1),这些法则与加法是相同的,只是不带进位,所以异或常被认作不进位加法。


以上是一位二进制的情况,下面考虑多位二进制的情况,称为按位异或(下面的内容以及题面都用 \oplus 表示按位异或):

按位异或是指将参与运算的两数各个二进位相异或,例如 3 \oplus 14=(0011)2(1110)2(0011)_2 \oplus (1110)_2= (1101)2(1101)_2 = 1313

在 C/C++/Python 中, 可以使用 ^ 来计算异或,即可以用 a ^ b 来直接计算 aba \oplus b 的值。


考虑如下问题:

在非负整数范围内进行考虑,给定一个正整数 cc,已知 ab=ca \oplus b = c,问 a+ba + b 的最小值为多少?

cc 的二进制表示写出来,可以得到一个 0101 串;对 cc 二进制表示的每一位考虑 aabb 该位的可能取值:

如果该位为 11,那么 (a,b)(a, b) 的取值为 (0,1)(0, 1) 或者 (1,0)(1, 0) ,显然这两种情况的和都是一样的,都为 11

如果该位为 00,那么 (a,b)(a, b) 的取值为 (0,0)(0, 0) 或者 (1,1)(1, 1) ,如果取值是 (1,1)(1,1) 那么加法会产生进位,为了让加法结果尽可能小,应该选取 (0,0)(0,0),结果为 00.

按以上取值可以发现 a+ba+b 的结果和 aba \oplus b 的结果是一样的,因为加法运算并没有产生进位,所以 a+ba + b 的最小值即为 cc.

题目描述

经过上面的学习,相信你已经很了解异或了,下面来挑战这道题吧:

在非负整数范围内进行考虑,给定两个正整数 ccdd ,问是否存在一组 (a,b)(a, b) 使得 ab=c,a+b=da \oplus b = c, a + b = d ?

你不需要给出 aabb 的具体值,你只需要判断是否存在即可。

输入格式

第一行一个整数 TT,代表测试数据组数。

接下来 TT 行,每行两个整数 ccdd,用空格隔开,含义见描述。

输出描述

对于每组测试数据,输出一行判断结果,输出"YES"代表存在对应的 aabb 的值,否则输出"NO".

样例输入

3
2023 2024
2024 2023
2024 2026

样例输出

NO
NO
YES

样例解释

对于第三组测试数据,我们可以让 a=2025,b=1a = 2025, b= 1,这样可以满足 ab=2024,a+b=2026a \oplus b = 2024, a + b = 2026.

数据范围与约定

测试点编号 每组测试数据约定 测试点分值
121 \sim 2 1d<c1001 \le d < c \le 100 每个测试点5分
353 \sim 5 1cd1001 \le c \le d \le 100
6106 \sim 10 1cd1051 \le c \le d \le 10^5
111511 \sim 15 1cd1091 \le c \le d \le 10^9 每个测试点10分

对于所有数据,1T1001 \le T \le 100