01字典树主要用于解决求异或最值问题.
简单模板:
int tol; // 节点数量
long long val[32 * MAXN]; //点的值
int ch[32 * MAXN][2]; //边的值
long long num[32 * MAXN] //点的数量
void init(){
tol = 1;
ch[0][0] = ch[0][1] = 0;
}
void insert(long long x){
//往01字典树中插入x
int u = 0;
for(int i = 32; i >= 0; i --){
int v = (x >> i) & 1;
if(!ch[u][v]){
//如果节点没有被访问过
ch[tol][0] = ch[tol][1] = 0;
//将当前节点的边值初始化
val[tol] = 0;
//节点值为0,表示到此为止不是一个数
ch[u][v] = tol++;
}
u = ch[u][v];
//下一节点
num[u]++;
//节点数量加+
}
val[u] = x;
//节点值为x,即到此为止是一个数
}
long long query(long long x){
//查询所有数中和x异或结果最大的树
int u = 0;
for(int i = 32; i >= 0; i--){
int v = (x >> i) & 1;
//利用贪心策略,优先寻找和当前位数不同的数
if(ch[u][v ^ 1]){
u = ch[u][v ^ 1];
} else{
u = ch[u][v];
}
}
return val[u];
}