异或最小值的题
贪心思路异或求最小,把二进制位从高位往低位写入字典树,如果高位能为0就为0,不能取0就取1即可
注意:数组不要开小会,一般里面几层for循环就乘以多大
AC代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=6e5+5;
int tire[30*maxn][2];
int w[30*maxn],cnt;//代表权值
int vis[maxn];
void insert_num(int x)
{
int root=0;
for(int i=31; i>=0; i--) //求异或值最小,故从后往前插入
{
int id=x>>i&1;
if(!tire[root][id])
tire[root][id]=++cnt;
root=tire[root][id];
}
w[root]=x;
}
int find_min(int x)
{
int root=0;
for(int i=31; i>=0; i--)
{
int id=x>>i&1;
if(tire[root][id^0])//贪心思路求最小
{
root=tire[root][id^0];
}
else
root=tire[root][id^1];
}
return w[root]^x;
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
for(int i=0; i<n; i++)
{
scanf("%d",&w[i]);
vis[w[i]]=1;
}
for(int i=0; i<=maxn; i++)
{
if(!vis[i])
insert_num(i);
}
int temp=0;
while(m--)
{
int x;
scanf("%d",&x);
temp=x^temp;
int ans=find_min(temp);
printf("%d\n",ans);
}
}