CF1870B题解报告
五年级蒟蒻的第五篇题解,望通过。
一道水题,但我想了蛮久。
我们先转化一下题意,设 \(b\) 中所选的数的按位或和为 \(x\),求 \({\LARGE \oplus}_{i=1}^{n} (a_i \operatorname{or} x)\) 的最大最小值。
有一个很容易理解的结论,如果 \(x\) 的二进制第 \(i\) 位为 \(1\),则 \(a_i \operatorname{or} x\) 的第 \(i\) 位也为 \(1\)。
接着分类讨论 \(n\) 的奇偶性即可。
在下文中,\(sxor = {\LARGE \oplus}_{i=1}^{n} a_i\),\(sor = b_1 \operatorname{or} b_2 \operatorname{or} \cdots \operatorname{or} b_m\)。
\(n\) 为偶数
所以 \(x\) 在二进制下为 \(1\) 的位为 \(0\)。
证明:若 \(x\) 的第 \(j\) 位为 \(1\),则 \(a_i \operatorname{or} x\) 的第 \(j\) 位也为 \(1\),偶数个 \(1\) 异或答案是 \(0\),证毕。
对于其他位,直接异或即可,答案为 \(sxor \operatorname{and} (\sim x)\)。
不难发现,当 \(x\) 中的 \(1\) 越多时,答案越小,\(x\) 中 \(0\) 越多时,答案越大。
所以最大最小时,\(x\) 分别取 \(0\) 和 \(sor\)。
\(n\) 为奇数
同上,\(x\) 在二进制下为 \(1\) 的位为 \(1\),对于其他位,直接异或即可,答案为 \(sxor \operatorname{or} x\)。
同上,所以最大最小时,\(x\) 分别取 \(sor\) 和 \(0\)。
code
位运算不加括号且使用 cout 的情况下会让你原地见祖宗。
#include<bits/stdc++.h>
using namespace std;
int t, n, m, a, b;
int sxor, sor;
void solve(){
cin >> n >> m;
sor = sxor = 0;
for(int i = 1; i <= n; i++)
cin >> a, sxor ^= a;
for(int i = 1; i <= m; i++)
cin >> b, sor |= b;
if(n % 2) cout << sxor << ' ' << (sxor | sor);
else cout << (sxor & (~sor)) << ' ' << sxor;
}
int main(){
ios::sync_with_stdio(0), cin.tie(0);
cin >> t;
while(t--) solve(), cout << "\n";
return 0;
}