给你
n
个正整数
有三种询问:
OR x
,查询
max(ai or x)
AND x
,查询
max(ai and x)
n,m≤100000 ,max(ai)<216
对于
xor
只要高位到低位依次满足尽量满足即可,相当与在
Trie
树上走。对与
and
和
or
有些位是填
0
或
#include<bits/stdc++.h>
const int A = 1 << 16;
template <typename T> void read(T &x) {
x = 0; char c = getchar();
for (; !isdigit(c); c = getchar());
for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
}
int n, q, x, sum[A];
bool exs[A], up[A];
char op[5];
int calc(int l, int r) {
if (!l) return sum[r];
return sum[r] - sum[l - 1];
}
int Xor(int x) {
int l = 0, r = A - 1, ans = 0;
for (int i=A>>1; l < r; i >>= 1) {
int mid = (l + r) >> 1;
if (x & i) {
if (calc(l, mid))
r = mid,
ans += i;
else
l = mid + 1;
}else {
if (calc(mid + 1, r))
l = mid + 1,
ans += i;
else
r = mid;
}
}
return ans;
}
int And(int x) {
for (int i=x; i>=0; i = (i - 1) & x)
if (up[i]) return i;
}
int Or(int x) {
int y = (A - 1) ^ x;
for (int i=y; i>=0; i = (i - 1) & y)
if (up[i]) return i | x;
}
int main() {
read(n); read(q);
while (n--)
read(x),
exs[x] = 1,
sum[x] = 1;
for (int i=1; i < A; i++)
sum[i] += sum[i - 1];
for (int i=0; i < A; i++)
if (exs[i])
for (int j=i; j>=0; j = (j - 1) & i) {
up[j] = 1;
if (!j) break;
}
while (q--) {
scanf("%s", op);read(x);
if (op[0] == 'X') printf("%d\n", Xor(x));
if (op[0] == 'A') printf("%d\n", And(x));
if (op[0] == 'O') printf("%d\n", Or(x));
}
return 0;
}