题目大意
给你(n)个数,对于每个数,让你找一个其他的数字与这个数异或为0,
解题思路
从二进制的角度考虑,两个数异或为0,即两个数的二进制位没有交集,对于一个数来说,它的补集以及它的补集的子集必定和它没有交集,所以我们只要判断一个数字的补集的子集中有没有数组中存在的数就可以了,这里可以用sos dp解决。我们设dp[i]为补集的状态空间,将所有数字(a_i)视为一个补集初始化(dp[a_i] = a_i),然后求出所有状态的子集中的一个解即可。
代码
const int maxn = 1e6+10;
const int maxm = 2e6+10;
int dp[1<<22], arr[maxn];
int main() {
IOS;
int n; cin >> n;
for (int i = 1; i<=n; ++i) cin >> arr[i];
int x = (1<<22)-1; clr(dp, 0xff);
for (int i = 1; i<=n; ++i) dp[arr[i]] = arr[i];
for (int i = 0; i<22; ++i)
for (int j = 0; j<(1<<22); ++j)
if ((j&(1<<i)) && dp[(j^(1<<i))]!=-1) dp[j] = dp[j^(1<<i)];
for (int i = 1; i<=n; ++i) cout << dp[arr[i]^x] << (i==n ? '
':' ');
return 0;
}