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 and and wrote the following equality on the board: where denotes the bitwise AND operation. Then he suggested his friend Petya find such a minimal () 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 (). The description of the test cases follows.
The only line of each test case contains two integers , ().
Output
For every test case, output the smallest possible value of such that equality holds.
If the equality does not hold for any , print instead.
We can show that if the required exists, it does not exceed .
Example
input
5 10 8 10 10 10 42 20 16 1000000000000000000 0
output
12 10 -1 24 1152921504606846976
Note
In the first example, , but , so the answer is .
In the second example, , so the answer is .
In the third example, we can see that the required does not exist, so we have to print .
解题思路
首先遍历和在二进制下的每一位,用来表示数字二进制的第位的数值,当遍历到第位时发现,,那么就必定无解。因为整个过程都是按位与的运算,如果,那么无论与什么数相与得到的结果都是而不可能得到。
接下来分类讨论:
- ,。那么可以取任何数,最终总是成立。
- ,。为了按位与后第位为,那么很明显应该让加上某个数后,这样才能有。很显然为了让的第位出现,可以取到无穷大,因此我们来看看最小可以取到多少。可以发现的第位要进位时才由变变,因此只用考虑由的前位所构成的数,即,第位进位后得到的结果为,因此的最小值为。
- ,。为了按位与后第位始终为,那么在的数中不能出现第位为的数。一样的,当的第位要进位时才由变变,考虑由的前位所构成的数,即,那么在进位前且第位仍为所能取到的最大值是,因此的取值不应超过。
然后对第种情况的所有取个最大值(即找到最大的下界)得到,对第种情况的所有取个最小值(即找到最小的上界)得到。如果说明有解,那么答案就是;否则就是无解。
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
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/17057484.html
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)