题目大意:给一个可以有相同数字的set 可以增减元素,询问每次提供一个x,y为set中的元素。z=max{max{y},max{y^x} } 求z的值。
题解:按位枚举,在第i位时得到与x第i位XOR位1的数(0 or 1) 然后查询set中符合条件的元素。由于中途得到的ans一定会<=最终答案,所以此处可以二分 也可以建立字典树。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 7100000
int a[maxn][2],n,siz,cal[maxn];
char st[10];
void ins(int x,int y)
{
int now=0,tmp;
for(int i=30;i>=0;i--)
{
tmp=(x>>i)&1;
if(!a[now][tmp]) siz++,a[now][tmp]=siz;
now=a[now][tmp];
cal[now]+=y;
}
}
int solve(int x)
{
int now=0,ans=0,tmp;
for(int i=30;i>=0;i--)
{
tmp=(x>>i)&1;
if(cal[a[now][tmp^1]])
{
ans+=(1<<i);
now=a[now][tmp^1];
}
else
{
now=a[now][tmp];
}
}
return ans;
}
int main()
{
int a,b,c;
scanf("%d",&n);
ins(0,1);
for(int i=1;i<=n;i++)
{
scanf("%s%d",st+1,&a);
if(st[1]=='+')
{
ins(a,1);
}
if(st[1]=='-')
{
ins(a,-1);
}
if(st[1]=='?')
{
printf("%d\n",solve(a));
}
}
return 0;
}
#include <set>
#include <iostream>
#include <algorithm>
using namespace std;
//#define DEBUG 1
multiset<int> s;
multiset<int>::iterator it;
int bit(int x, int i) {
return (x >> i) & 1;
}
int check(int a, int b) {
it = s.lower_bound(a);
if (it == s.end()) return 0;
if ((*it) < b) return 1;
else return 0;
}
int solve(int x) {
int tmp, ans = 0;
for (int i = 30; i >= 0; --i) {
tmp = bit(x, i);
if (!tmp) ans |= (1LL << i);
if (!check(ans, ans + (1LL << i))) ans ^= (1LL << i);
}
return (ans ^ x);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
char op;
int q, x;
s.insert(0);
cin >> q;
while (q--) {
cin >> op >> x;
if (op == '+') {
s.insert(x);
} else if (op == '-') {
it = s.find(x);
s.erase(it);
} else {
cout << solve(x) << endl;
}
}
#ifdef DEBUG
system("pause");
#endif // DEBUG
return 0;
}