CJJ
异或是对应的每位相同为0,不同为1.
根据题意,我们会想到肯定要让x和每位都与他尽量不同的抑或比较好。
所以可以建立一颗字典树,先把整个数组都插入字典树。字典树的每个分叉就表示0,1的分界。
从高位到低位。这样我们就可以一层一层,一位一位的比较,每次走不同的那边就好了。
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1e5+5;
struct node
{
int son[2];
}tree[40*maxn];
int root,tot;
int newnode()
{
tot++;
tree[tot].son[0]=tree[tot].son[1]=-1;
return tot;
}
void insert(int x)
{
int now=root;
for(int i=30;i>=0;i--)
{
int tmp=!!(x&(1<<i)); //控制在01之间
if(tree[now].son[tmp]==-1)tree[now].son[tmp]=newnode();
now=tree[now].son[tmp];
}
}
int query(int x)
{
int ans=0;
int now=root;
for(int i=30;i>=0;i--)
{
int tmp=!(x&(1<<i));
if(tree[now].son[tmp]==-1)now=tree[now].son[tmp^1];
else
{
ans+=(1<<i);
now=tree[now].son[tmp];
}
}
return ans;
}
int main()
{
int t;
cin>>t;
while(t--)
{
tot=-1;
root=newnode();
int n,q;
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
insert(x);
}
int y=0;
while(q--)
{
int op;
scanf("%d",&op);
if(op==1)
{
int x;
scanf("%d",&x);
y^=x;
}
else
{
int x;
scanf("%d",&x);
printf("%d\n",query(x^y));
}
}
}
return 0;
}
<br /><span id="_xhe_temp" width="0" height="0"><br /></span>