CodeForces 165E Compatible Numbers
description
Two integers x and y are compatible, if the result of their bitwise "AND" equals zero, that is, a & b = 0. For example, numbers 90 (10110102) and 36 (1001002) are compatible, as 10110102 & 1001002 = 02, and numbers 3 (112) and 6 (1102) are not compatible, as 112 & 1102 = 102.
You are given an array of integers a1, a2, ..., an. Your task is to find the following for each array element: is this element compatible with some other element from the given array? If the answer to this question is positive, then you also should find any suitable element.
给出n个数,对于每个数找出任意一个与之相与为0的数,没有输出0
limit
n <= 1e6 , 1 <= \(a_i\) <= 4e6
Example
input1
2
90 36
output1
36 90
input2
4
3 6 3 6
output2
-1 -1 -1 -1
input3
5
10 6 9 8 2
output3
-1 8 2 2 8
solution
对于一个数x找和它相与值为0的数,可以先将x按位取反,将取反得到的数记为y,将要找的与x值为0的数记为z,那么y的二进制中,若某一位为0,z的这一位也要是0,若y的某一位为1,那么z的这一位可以是0也可以是1.这类似于一个高维的前缀和。查找z的过程就是看前缀和y是否不为0.
设\(f[state]\)表示state这个状态能否由 \(a_i\)中某一个 的 二进制 的某些位 从0变成1 得来,\(g[state]\)则用来记录这个state是由哪个初始的\(a_i\)变化而来。
#include<iostream>
using namespace std;
const int N = 1e6+10;
int n;
int A[N] , f[1 << 22] , g[1 << 22];
int main()
{
cin >> n;
for(int i = 1 ; i <= n ; ++i)
cin >> A[i];
for(int i = 1 ; i <= n ; ++i)
f[A[i]] = 1 , g[A[i]] = A[i];
for(int i = 0 ; i < (1 << 22) ; ++i) if(f[i])
{
for(int j = 0 ; j < 22 ; ++j)
if(!(i & (1 << j)))
f[i | (1 << j)] = 1 , g[i | (1 << j)] = g[i];
}
for(int i = 1 ; i <= n ; ++i)
{
int y = (~A[i]) & ((1 << 22) - 1);
if(f[y])
cout << g[y] << ' ';
else
cout << -1 << ' ';
}
return 0;
}

浙公网安备 33010602011771号