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");
}
}
}