因此不难想到维护01字典树,由于数值最大为109,因此字典树深度最深为32,即维护32个二进制位。字典树中每个节点的flag记录这个节点被遍历了多少次,插入或删除一个元素,即将元素二进制状态下经过的节点 flag +1 / -1。最后考虑求与x异或值最大的y,将x的二进制形式输入字典树,每一层尽量走与x二进制位置不同的那个节点,最后能够找到一条路径,将路径上所有二进制位加起来,即得到了y。
代码:
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)#define rep(i,a,b) for(int i = a; i <= b; i++)#define LOG1(x1,x2) cout << x1 << ": " << x2 << endl;#define LOG2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;#define LOG3(x1,x2,y1,y2,z1,z2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << " , " << z1 << ": " << z2 << endl;typedeflonglong ll;typedefdouble db;constint N =1e5+100;constint M =1e5+100;constint charset =3;constint max_node =2*1e5*32+100;const db EPS =1e-9;usingnamespace std;int q;char op[10];int ss[40];struct Trie
{int tot,root,child[max_node][charset];//root:根节点 tot:节点编号//child[i][j]=k,表示编号为i的节点的第j个孩子是编号为k的节点int flag[max_node];//是否以某一个字符为结束Trie(){// memset(child,0,sizeof(child));memset(flag,0,sizeof(flag));
root = tot =1;//根节点编号为1 }voidmem()//将字典树初始化 {memset(child,0,sizeof(child));memset(flag,0,sizeof(flag));
root = tot =1;//根节点编号为1 }voiddele(){int cur = root;for(int i =1; i<=32; i++){int x = ss[i];
cur = child[cur][x];
flag[cur]--;}}voidinsert(){int cur = root;for(int i =1; i<=32; i++){int x = ss[i];// LOG2("i",i,"x",x);// LOG1("cur_y",child[cur][1]);if(child[cur][x]==0)
child[cur][x]=++tot;
cur = child[cur][x];
flag[cur]++;}}intquery(){int tp =0;int cur = root;for(int i =1; i <=32; i++){int x = ss[i],y;if(x ==1) y =0;else y =1;// LOG3("i",i,"x",x,"y",y);// LOG1("cur_y",child[cur][y]);if(child[cur][y]!=0&& flag[child[cur][y]]>=1){if(y ==1) tp +=(1<<(32-i));
cur = child[cur][y];// printf("in y\n");}else{if(x ==1) tp +=(1<<(32-i));
cur = child[cur][x];// printf("in x\n");}}return tp;//查询单词时应该 return flag[cur]; }}tre;intmain(){scanf("%d",&q);memset(ss,0,sizeof ss);
tre.insert();rep(i,1,q){scanf("%s",op);if(op[0]=='+'){int xx, pos =32;scanf("%d",&xx);memset(ss,0,sizeof ss);while(xx){if(xx&1) ss[pos]=1;
xx /=2;
pos--;}// rep(i,1,32) printf("%d ",ss[i]);// printf(" ");
tre.insert();}elseif(op[0]=='-'){int xx, pos =32;scanf("%d",&xx);memset(ss,0,sizeof ss);while(xx){if(xx&1) ss[pos]=1;
xx /=2;
pos--;}
tre.dele();}else{int xx, pos =32, base;scanf("%d",&xx);
base = xx;memset(ss,0,sizeof ss);while(xx){if(xx&1) ss[pos]=1;
xx /=2;
pos--;}int yy = tre.query();// LOG2("base",base,"yy",yy);
ll ans =((ll)yy)^((ll)base);printf("%lld\n",ans);}}return0;}