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;
}
posted @ 2022-10-22 22:37  沙野博士  阅读(64)  评论(0)    收藏  举报