01字典树(待更新)

Posted Yeader

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了01字典树(待更新)相关的知识,希望对你有一定的参考价值。

01字典树典型的题就是找出异或值最大的两个数,其实跟字典树差不多的,就是从原来的26位字母变成了0和1,插入操作也跟字典树差不多,查询的时候有贪心思想,尽量找同位不相同的。

模板:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int N=1e5+5;
 8 
 9 struct node{
10     int next[2];
11     int val;
12     void reset(){
13         next[0]=next[1]=val=0;
14     }
15 }T[N*32];//数组大小为数字个数*最大位数 
16 
17 int cnt;//字典树上的节点个数
18 
19 void init(){
20     cnt=0;
21     T[0].reset();
22 } 
23 
24 //将x插入到01字典树上 
25 void insert(int x){
26     int cur=0;//从根节点开始
27     for(int i=31;i>=0;i--){
28         int t=(x>>i)&1;
29         if(!T[cur].next[t]){
30             //将下一个新节点初始化
31             T[++cnt].reset();
32             T[cur].next[t]=cnt;
33         }
34         cur=T[cur].next[t];
35     }
36     //插入x 
37     T[cur].val=x;
38 }
39 
40 //查询在字典树中查找和x异或的值最大的元素 
41 int query(int x){
42     int cur=0;
43     for(int i=31;i>=0;i--){
44         int t=(x>>i)&1;
45         //贪心,尽量找不同的使异或值最大 
46         if(T[cur].next[t^1])
47             cur=T[cur].next[t^1];
48         else
49             cur=T[cur].next[t];
50     }
51     return T[cur].val;
52 }

下面几道例题:

一、HDU 4825 xor sum

给你n个数,m次查询,输出n个数中与查询地数x异或值最大的数,模板题

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int N=1e5+5;

struct node{
    int next[2];
    int val;
    void reset(){
        next[0]=next[1]=val=0;
    }
}T[N*32];//数组大小为数字个数*最大位数 

int cnt;//字典树上的节点个数

void init(){
    cnt=0;
    T[0].reset();
} 

//将x插入到01字典树上 
void insert(int x){
    int cur=0;//从根节点开始
    for(int i=31;i>=0;i--){
        int t=(x>>i)&1;
        if(!T[cur].next[t]){
            //将下一个新节点初始化
            T[++cnt].reset();
            T[cur].next[t]=cnt;
        }
        cur=T[cur].next[t];
    }
    //插入x 
    T[cur].val=x;
}

//查询在字典树中查找和x异或的值最大的元素 
int query(int x){
    int cur=0;
    for(int i=31;i>=0;i--){
        int t=(x>>i)&1;
        //贪心,尽量找不同的使异或值最大 
        if(T[cur].next[t^1])
            cur=T[cur].next[t^1];
        else
            cur=T[cur].next[t];
    }
    return T[cur].val;
}

int main(){
    int t,cas=0;
    scanf("%d",&t);
    while(t--){
        init();
        int n,m,x;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&x);
            insert(x);
        }
        printf("Case #%d:\n",++cas);
        for(int i=1;i<=m;i++){
            scanf("%d",&x);
            printf("%d\n",query(x));
        }
    }
    return 0;
}

 

以上是关于01字典树(待更新)的主要内容,如果未能解决你的问题,请参考以下文章

待更新算法

01字典树

cf842D 01字典树|线段树 模板见hdu4825

字典树目录

Chip Factory(HDU5536 + 暴力 || 01字典树)

优先队列 + 并查集 + 字典树 + 树状数组 + 线段树 + 线段树点更新 + KMP +AC自动机 + 扫描线