D. ConstructOR

D. ConstructOR

You are given three integers a, b, and d. Your task is to find any integer x which satisfies all of the following conditions, or determine that no such integers exist:

  • 0x<260;
  • a|x is divisible by d;
  • b|x is divisible by d.

Here, | denotes the bitwise OR operation.

Input

Each test contains multiple test cases. The first line of input contains one integer t (1t104) — the number of test cases.

Each test case consists of one line, containing three integers a, b, and d (1a,b,d<230).

Output

For each test case print one integer. If there exists an integer x which satisfies all of the conditions from the statement, print x. Otherwise, print 1.

If there are multiple solutions, you may print any of them.

Example

input

复制代码
8
12 39 5
6 8 14
100 200 200
3 4 6
2 2 2
18 27 3
420 666 69
987654321 123456789 999999999
复制代码

output

18
14
-1
-1
0
11
25599
184470016815529983

Note

In the first test case, x=18 is one of the possible solutions, since 39|18=55 and 12|18=30, both of which are multiples of d=5.

In the second test case, x=14 is one of the possible solutions, since 8|14=6|14=14, which is a multiple of d=14.

In the third and fourth test cases, we can show that there are no solutions.

 

解题思路

  首先先确定无解的情况,对于d根据lowbit求出其二进制下末尾0的个数,假设为k。如果ab在二进制下末尾0的个数小于k,那么一定无解。这是因为d含有因子2k,而ab以及按位或后的结果都不可能含有因子2k,因此无解。

  下面给出一种答案x的构造方案,让a|x=b|x=x,同时x也是d的倍数,这样至少可以保证a|xb|x能被d整除(下面再证明x一定满足x<260)。

  由于a,b<230,因此在第0到第29位中,如果ab的第i位为1,那么x的第i为也应该要为1,这样就可以保证a|x=b|x=x

  那么如何保证xd的倍数呢?当x的第i位要变成1时,我们直接让x加上d2ik倍,即加上2ik×d2ik×d等价于把d左移ik位,这意味着d的最低位的1从第k位左移到了第i位,而此时x的第i位为0,因此x加上2ik×d后第i位就变成了1,同时这样也保证了x始终是d的倍数。

  下面来证明按照上面的构造方法得到的x一定是满足x<260。考虑最糟糕的情况:x=20×d+21×d++229×d=123012×d=(2301)×d<230×230=260

  AC代码如下:

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 
 6 int lowbit(LL x) {
 7     return x & -x;
 8 }
 9 
10 void solve() {
11     LL a, b, d;
12     scanf("%lld %lld %lld", &a, &b, &d);
13     LL ret = 0;
14     if (lowbit(a) < lowbit(d) || lowbit(b) < lowbit(d)) {   // a或b末尾0的个数小于d末尾0的个数
15         ret = -1;
16     }
17     else {
18         int k = log2(lowbit(d));    // d末尾0的个数
19         a |= b;
20         for (int i = k; i < 30; i++) {
21             // 如果a或b的第i位为1,并且此时x的第i位为0
22             if ((a >> i & 1) && (ret >> i & 1) == 0) ret += d << i - k; // 答案加上d * 2^(i-k)
23         }
24     }
25     printf("%lld\n", ret);
26 }
27 
28 int main() {
29     int t;
30     scanf("%d", &t);
31     while (t--) {
32         solve();
33     }
34     
35     return 0;
36 }
复制代码

 

参考资料

  Codeforces Round #833 (Div. 2) A - D:https://zhuanlan.zhihu.com/p/582927038

  Codeforces Round #833 (Div. 2) A-D.md:https://www.cnblogs.com/BlankYang/p/16885937.html

posted @   onlyblues  阅读(95)  评论(4编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示