Vasiliy‘s Multiset(字典树)

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:

  1. "+ x" — add integer xx to multiset AA .
  2. "- 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.
  3. "? 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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值