Codeforces Round #367 (Div. 2) D
题意:
有如下三种操作:
- "+ x"向堆中加入值为x的值;
- "- x"从堆中减去一个值为x的元素,保证x在堆中;
- "? x"询问堆A中与x异或值最大的数的值是多少,输出最大值。
然后就是字典树的一般操作了,可惜卡C卡了点时间,赛后十分钟才写完。
记住一种特殊情况,如果你没往堆中放0,堆中也是有0的。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 8e6 + 7;
int Q;
int x;
char op[3];
int tot = 0, waste[maxN], inwast = 0;
struct node
{
int nex[2], num;
node(int a=0, int b=0, int c=0):nex{a, b}, num(c) {}
void init() { nex[0] = nex[1] = 0; num = 0; }
}trie[maxN];
void Insert(int x)
{
int root = 0;
for(int i=31, id; i>=0; i--)
{
id = (x >> i) & 1;
if(!trie[root].nex[id])
{
if(inwast) trie[root].nex[id] = waste[inwast--];
else trie[root].nex[id] = ++tot;
trie[trie[root].nex[id]].init();
}
root = trie[root].nex[id];
trie[root].num++;
}
}
void del(int x)
{
int root = 0, nex;
for(int i=31, id; i>=0; i--)
{
id = (x >> i) & 1;
nex = trie[root].nex[id];
if(--trie[nex].num == 0)
{
trie[root].nex[id] = 0;
waste[++inwast] = nex;
}
root = nex;
}
}
int fid(int x)
{
int root = 0, ans = 0;
for(int i=31, id; i>=0; i--)
{
id = (x >> i) & 1;
if(trie[root].nex[!id])
{
ans |= (1 << i);
root = trie[root].nex[!id];
}
else root = trie[root].nex[id];
}
return ans;
}
int main()
{
scanf("%d", &Q);
Insert(0);
while(Q--)
{
scanf("%s%d", op, &x);
if(op[0] == '+')
{
Insert(x);
}
else if(op[0] == '-')
{
del(x);
}
else
{
printf("%d\n", fid(x));
}
}
return 0;
}