HRBUST 2457——判断数字【二进制、位运算】

题目传送门


Description

给定N个数字,第i个数字的大小为a[i],请问ai是否存在aj使得(a[i] and a[j])的结果为0


Input

数据组数小于等于10 每组输入一共两行, 第一行一个数字N,表示数字个数 第二行N个数字,表示a[1]~a[N]


Output

每组输出一共N行,表示对于a[i]来说,是否存在一个aj使得(a[i] and a[j])的结果为0 存在则输出"YES",否则输出"NO"


Sample Input

5

1 2 3 4 5

2

1 1


Sample Output

YES

YES

YES

YES

YES

NO

NO


Hint

1<=a[i]<=1000000

N<=1000000


Source

"科林明伦杯"哈尔滨理工大学第九届程序设计团队赛


分析

  • 对于某个数 a ,先得到肯定和 a 按位与得0的数,即 k & a = 0,
    易得 k = a ^ maxn(11111…1111)
  • 对于 k 的每位的 1 ,逐渐删减,暴力 ,记录仍然和 a 按位与得 0 的值
  • 暴力找一遍即可

AC-Code

#include<bits/stdc++.h>
	using namespace std;
	typedef long long ll;
	const ll maxn = (1 << 20) - 1;
	ll a[maxn + 5], dp[maxn + 5];
	int main() {
		ll n;
		while (scanf("%lld", &n) == 1) {
			memset(dp, 0, sizeof(dp));
			for (int i = 1; i <= n; i++) {
				scanf("%lld", &a[i]);
				dp[maxn ^ a[i]] = 1;
			}
			for (int i = maxn; i >= 1; i--) {
				if (dp[i]) {
					for (int j = 0; j <= 20; j++) {
						if (i & (1 << j)) {
							dp[i ^ (1 << j)] = 1;
						}
					}
				}
			}
			for (int i = 1; i <= n; i++) {
				if (dp[a[i]]) printf("YES\n");
				else printf("NO\n");
			}
		}

	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值