nefu1248智力異或 字典樹
阿新 • • 發佈:2019-01-05
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>