https://www.luogu.com.cn/problem/CF706D
https://codeforces.com/problemset/problem/706/D
题目描述
Author has gone out of the stories about Vasiliy, so here is just a formal task description.
You are given qq queries and a multiset AA , initially containing only integer 00 . There are three types of queries:
- "+ x" — add integer xx to multiset AA .
- "- x" — erase one occurrence of integer xx from multiset AA . It's guaranteed that at least one xx is present in the multiset AA before this query.
- "? x" — you are given integer xx and need to compute the value , i.e. the maximum value of bitwise exclusive OR (also know as XOR) of integer xx and some integer yy from the multiset AA .
Multiset is a set, where equal elements are allowed.
输入格式
The first line of the input contains a single integer qq ( 1<=q<=2000001<=q<=200000 ) — the number of queries Vasiliy has to perform.
Each of the following qq lines of the input contains one of three characters '+', '-' or '?' and an integer x_{i}xi ( 1<=x_{i}<=10^{9}1<=xi<=109 ). It's guaranteed that there is at least one query of the third type.
Note, that the integer 00 will always be present in the set AA .
输出格式
For each query of the type '?' print one integer — the maximum value of bitwise exclusive OR (XOR) of integer x_{i}xi and some integer from the multiset AA .
题意翻译
有q次操作和一个集合A,开始时集合中只有一个数0,下面有三种类型的操作:
1. + x 把x插入集合A
2. - x 把x从集合A中删去,保证x已存在于集合A中
3. ? x 给一个数x在集合A中找一个y使得x^y最大,并求出这个值
数据范围:$1\leq q\leq 200000$ $1\leq x_i\leq10^9$
输入输出样例
输入 #1复制
10 + 8 + 9 + 11 + 6 + 1 ? 3 - 8 ? 3 ? 8 ? 11
输出 #1复制
11 10 14 13
说明/提示
After first five operations multiset AA contains integers 00 , 88 , 99 , 1111 , 66 and 11 .
The answer for the sixth query is integer — maximum among integers , , , and .
其实字典树还是很明显的,因为有一个最大异或值,比较经典。自己没怎么碰过字典树上删除的,这道题学到了字典树上的删除,就是打一个节点的经过次数就好了。
另外记录一下字典树的理解:
一个二维数组tire[maxn][26],然后tire[i][j] = p 代表编号为i的节点的第j个孩子是编号为p的节点
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=10000005;
typedef int LL;
LL tree[maxn][2];
LL sum[maxn],vis[maxn];
LL tot=1,root=1;
void insert(LL x,LL add)
{
LL p=root;sum[p]+=add;
for(LL i=31;i>=0;i--)
{
// LL t=x&(1<<i);
LL t=x>>i&1;//判当前位是0/1
if(!tree[p][t]) tree[p][t]=++tot;
p=tree[p][t];
sum[p]+=add;
}
}
inline void query(LL x)
{
LL res=0;LL p=root;
for(LL i=31;i>=0;i--)
{
//LL t=x&(1<<i);
LL t=x>>i&1;
if(t==0)
{
if(sum[tree[p][1]])
{
res+=(1<<i);
p=tree[p][1];
}
else p=tree[p][0];
}
else if(t==1)
{
if(sum[tree[p][0]])
{
res+=(1<<i);
p=tree[p][0];
}
else p=tree[p][1];
}
}
cout<<res<<endl;
}
int main(void)
{
//cin.tie(0);std::ios::sync_with_stdio(false);
LL q;cin>>q;
insert(0,1);// ? 1 开始就询问
while(q--)
{
char op[10];LL x;
cin>>op; cin>>x;
if(op[0]=='+') insert(x,1);
if(op[0]=='-') insert(x,-1);
if(op[0]=='?') query(x);
}
return 0;
}