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:
- $0 \leq x < {2}^{60}$;
- $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$ $(1 \leq t \leq {10}^{4})$ — the number of test cases.
Each test case consists of one line, containing three integers $a$, $b$, and $d$ $(1 \leq a,b,d < {2}^{30})$.
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$根据$\text{lowbit}$求出其二进制下末尾$0$的个数,假设为$k$。如果$a$或$b$在二进制下末尾$0$的个数小于$k$,那么一定无解。这是因为$d$含有因子$2^k$,而$a$或$b$包括按位或后的结果都不可能含有因子$2^k$,因此无解。
下面给出一种答案$x$的构造方案,让$a|x = b|x = x$,同时$x$也是$d$的倍数,这样至少可以保证$a|x$和$b|x$能被$d$整除(下面再证明$x$一定满足$x < 2^{60}$)。
由于$a, b < 2^{30}$,因此在第$0$到第$29$位中,如果$a$或$b$的第$i$位为$1$,那么$x$的第$i$为也应该要为$1$,这样就可以保证$a|x = b|x = x$。
那么如何保证$x$是$d$的倍数呢?当$x$的第$i$位要变成$1$时,我们直接让$x$加上$d$的$2^{i- k}$倍,即加上$2^{i-k} \times d$。$2^{i-k} \times d$等价于把$d$左移$i-k$位,这意味着$d$的最低位的$1$从第$k$位左移到了第$i$位,而此时$x$的第$i$位为$0$,因此$x$加上$2^{i-k} \times d$后第$i$位就变成了$1$,同时这样也保证了$x$始终是$d$的倍数。
下面来证明按照上面的构造方法得到的$x$一定是满足$x < 2^{60}$。考虑最糟糕的情况:$$\begin{align*} x &= 2^0 \times d + 2^1 \times d + \ldots + 2^{29} \times d \\ &= \frac{1 - 2^{30}}{1 - 2} \times d \\ &= \left( {2^{30} - 1} \right) \times d \\ &< 2^{30} \times 2^{30} = 2^{60} \end{align*}$$
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
标签:14,lowbit,30,times,ConstructOR,test,18 From: https://www.cnblogs.com/onlyblues/p/16893690.html