异或求最小值模板
#include <bits/stdc++.h>
using namespace std;
const int maxn=300005;
int n,m;
int a[maxn],b[maxn];
int ch[30*maxn][2];
int val[30*maxn];
int sz;
void insert(int num){
int u=0;
for(int i=29;i>=0;i--){
int c=((num>>i)&1);
if(!ch[u][c]){
ch[u][c]=++sz;
}
u=ch[u][c];
val[u]++;
}
}
void remove(int num)
{
int u=0;
for(int i=29;i>=0;i--)
{
int c=((num>>i)&1);
int pre = u;
u = ch[u][c];
if(--val[u]==0) ch[pre][c]=0;
}
}
int query(int num){
int p=0,v=0;
for(int i=29;i>=0;i--)
{
int c=((num>>i)&1);
if(ch[p][c])p=ch[p][c];
else
{
p=ch[p][c^1];
v+=(1<<i);
}
}
return v;
} 异或求最大值模板:
#include <bits/stdc++.h>
using namespace std;
#define Memset(x, a) memset(x, a, sizeof(x))
#define _for(i,a,b) for(int i=a;i<=b;i++)
const int maxn = 600007;//集合中的数字个数
int ch[32*maxn][2]; //节点的边信息
long long val[32*maxn]; //节点存储的值
long long a[maxn];
int sz,q,n; //树中当前节点个数
long long num;
void init(){
Memset(ch[0],0); //树清空
sz=1;
}
void _insert(long long a){
int u=0;
for(int i=32;i>=0;i--){
int c=((a>>i)&1);
if(!ch[u][c]){
Memset(ch[sz],0);
ch[u][c]=sz++;
}
u=ch[u][c];
++val[u];
}
}
void _delete(long long a){
int u=0;
for (int i=32; i>=0; --i){
int c=((a>>i)&1);
u=ch[u][c];
--val[u];
}
}
long long query(long long a){
int u=0;
long long ans=0;
for(int i=32;i>=0;i--){
int c=((a>>i)&1);
if (c==1){
if (ch[u][0] && val[ch[u][0]]){
ans+=1<<i;
u=ch[u][0];
}
else
u=ch[u][1];
}
else{
if (ch[u][1] && val[ch[u][1]]){
ans+=1<<i;
u=ch[u][1];
}
else
u=ch[u][0];
}
}
return ans;
}
这篇博客介绍了如何利用字典树数据结构来高效地求解异或操作后的最大值和最小值。内容包括异或求最大值的模板,并讨论了在数据集中进行删除操作时如何维护这些值。对于需要频繁查询和更新异或结果的场景,这种方法提供了一种高效的解决方案。

977

被折叠的 条评论
为什么被折叠?



