模拟赛题。我知道是其他比赛的题,但是不清楚luogu有没有。
题目:
我们定义 A "包含" B 的概念是 A&B=B ,其中&是位运算中的“按位与"。
现在给出一个集合 Q, 这个集合 n 个正整数, m 次询问。每次询问给出一个数字 x, 请回答集合 Q 中是否有一个数字包含 x 。
第一行输入两个正整数 n,m, 意义如题面所示。
接下来一行输入 n 个正整数, 描述集合 Q 中的数字, 其中第 i 个数字为 ai 。
然后有 m 行, 每行给出一个正整数 x, 代表询问。
对于每一个询问, 输出 yes 或 no 表示答案。
2 2
3 7
4
9
yes
no
对于 20% 的数据, 满足 n≤105,m≤10,1≤x,ai≤1000 对于 40% 的数据, 满足 n≤105,m≤105,1≤x,ai≤1000
对于 100% 的数据, 满足 1≤n≤105,1≤m≤105,1≤x,ai≤106
代码(80pts)
#include <bits/stdc++.h>
using namespace std;
int f [500005] [20], n, m, x, lg [500005];
int query (int l, int r) {
int q = lg [r - l + 1];
return f [l] [q] | f [r - (1 << q) + 1] [q];
}
bool search (int x, int l, int r) {
int q = query (l, r);
if ((q & x) != x)
return false;
if (l >= r)
return (q & x) == x;
int mid = (l + r) / 2;
return search (x, l, mid) || search (x, mid + 1, r);
}
int main () {
cin >> n >> m;
lg [1] = 0;
for (int i = 2 ; i <= n ; i ++) {
lg [i] = lg [i - 1] + !(i & (i - 1));
}
for (int i = 1 ; i <= n ; i ++) {
cin >> f [i] [0];
}
for (int j = 1 ; j <= 17 ; j ++) {
for (int i = 1 ; i <= n ; i ++) {
f [i] [j] = f [i] [j - 1] | f [i + (1 << (j - 1))] [j - 1];
}
}
for (int i = 1 ; i <= m ; i ++) {
cin >> x;
if (search (x, 1, n)) {
cout << "yes\n";
} else {
cout << "no\n";
}
}
return 0;
}