C. Interesting Sequence

C. Interesting Sequence

Petya and his friend, robot Petya++, like to solve exciting math problems.

One day Petya++ came up with the numbers $n$ and $x$ and wrote the following equality on the board: $$n\ \&\ (n+1)\ \&\ \dots\ \&\ m = x,$$ where $\&$ denotes the bitwise AND operation. Then he suggested his friend Petya find such a minimal $m$ ($m \ge n$) that the equality on the board holds.

Unfortunately, Petya couldn't solve this problem in his head and decided to ask for computer help. He quickly wrote a program and found the answer.

Can you solve this difficult problem?

Input

Each test contains multiple test cases. The first line contains the number of test cases $t$ ($1 \le t \le 2000$). The description of the test cases follows.

The only line of each test case contains two integers $n$, $x$ ($0\le n, x \le 10^{18}$).

Output

For every test case, output the smallest possible value of $m$ such that equality holds.

If the equality does not hold for any $m$, print $-1$ instead.

We can show that if the required $m$ exists, it does not exceed $5 \cdot 10^{18}$.

Example

input

5
10 8
10 10
10 42
20 16
1000000000000000000 0

output

12
10
-1
24
1152921504606846976

Note

In the first example, $10\ \&\ 11 = 10$, but $10\ \&\ 11\ \&\ 12 = 8$, so the answer is $12$.

In the second example, $10 = 10$, so the answer is $10$.

In the third example, we can see that the required $m$ does not exist, so we have to print $-1$.

 

解题思路

  首先遍历$n$和$x$在二进制下的每一位,用$n_k$来表示数字$n$二进制的第$k$位的数值,当遍历到第$k$位时发现$n_k = 0$,$x_k = 1$,那么就必定无解。因为整个过程都是按位与的运算,如果$n_k = 0$,那么无论与什么数相与得到的结果都是$0$而不可能得到$1$。

  接下来分类讨论:

  1. $n_k = 0$,$x_k = 0$。那么$m$可以取任何数,最终$n_k\ \&\ (n+1)_k\ \& \ \dots\ \&\ m_k = x_k = 0$总是成立。
  2. $n_k = 1$,$x_k = 0$。为了按位与后第$k$位为$0$,那么很明显应该让$n$加上某个数$s$后$(n+s)_{k} = 0$,这样才能有$n_k\ \&\ (n+1)_k\ \&\ \dots\ (n+s)_k\ \&\ \dots\ \&\ m_k = x_k = 0$。很显然为了让$n+s$的第$k$位出现$0$,$s$可以取到无穷大,因此我们来看看$s$最小可以取到多少。可以发现$n$的第$k$位要进位时才由变$1$变$0$,因此只用考虑由$n$的前$k$位所构成的数,即$n\ \%\ {2^{k+1}}$,第$k$位进位后得到的结果为$2^{k+1}$,因此$s$的最小值为$2^{k+1} - n\ \%\ {2^{k+1}}$。
  3. $n_k = 1$,$x_k = 1$。为了按位与后第$k$位始终为$1$,那么在$n \sim m$的数中不能出现第$k$位为$0$的数。一样的,当$n$的第$k$位要进位时才由变$1$变$0$,考虑由$n$的前$k$位所构成的数,即$n\ \%\ {2^{k+1}}$,那么在进位前且第$k$位仍为$1$所能取到的最大值是$2^{k+1}-1$,因此$s$的取值不应超过$2^{k+1}-1 - n\ \%\ {2^{k+1}}$。

  然后对第$2$种情况的所有$s$取个最大值(即找到最大的下界)得到$l$,对第$3$种情况的所有$s$取个最小值(即找到最小的上界)得到$r$。如果$l \leq r$说明有解,那么答案就是$m = n + l$;否则就是无解。

  AC代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 
 6 void solve() {
 7     LL n, m;
 8     scanf("%lld %lld", &n, &m);
 9     LL l = 0, r = 9e18;
10     for (int i = 0; i < 60; i++) {    // 1e18的二进制位最多有60位
11         LL x = n % (1ll << i + 1);    // 得到n的前i位所构成的数
12         int a = n >> i & 1, b = m >> i & 1;
13         if (!a && b) {    // n的第k位为0,m的第k位为1,无解
14             printf("-1\n");
15             return;
16         }
17         if (a && !b) l = max(l, (1ll << i + 1) - x);    // 第一种情况
18         else if (a && b) r = min(r, (1ll << i + 1) - 1 - x);    // 第二种情况
19     }
20     printf("%lld\n", l <= r ? n + l : -1);
21 }
22 
23 int main() {
24     int t;
25     scanf("%d", &t);
26     while (t--) {
27         solve();
28     }
29     
30     return 0;
31 }

 

参考资料

  Codeforces Round #843 (Div. 2) C (思维):https://zhuanlan.zhihu.com/p/598221402

原文链接: https://www.cnblogs.com/onlyblues/p/17057484.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    C. Interesting Sequence

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/312791

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月16日 下午12:31
下一篇 2023年2月16日 下午12:32

相关推荐