Skip to content

01字典树

什么是?

用于解决一些异或问题,也可以用于模拟平衡树(但是我不会)

譬如对求一组数和x的最大异或值

策略

如果我们要找与给定数异或最大的数,就尽可能走与该数当前位不同的路径 反之则尽可能走与当前位相同的路径

值得注意的是应该从最高位开始走,这是个要注意的贪心的点,因为最高位贡献大

标准模板

cpp
int nxt[(int)5e6+1][2];
int cnt=0;
void insert(int v){
    int cur=0;
    for(int i=30;i>=0;i--){
        int p=(v>>i)&1;
        if(!nxt[cur][p])nxt[cur][p]=++cnt;
        cur=nxt[cur][p];
    }
}
int get(int v){
    int cur=0,val=0;
    for(int i=30;i>=0;i--){
        int p=(v>>i)&1;
        if(nxt[cur][p^1]){
            cur=nxt[cur][p^1];
            val+=1<<i;
            continue;
        }
        cur=nxt[cur][p];
    }
    return val;
}
py
MAXBIT = 31

nxt = [[0,0]]
num = {}
global cnt
cnt=1
def insert(n):
    global cnt
    cur = 1
    for i in range(MAXBIT, -1, -1):
        bit = (n >> i) & 1
        while cur+1>=len(nxt):
            nxt.append([0,0])
        if not nxt[cur][bit]:
            cnt += 1
            nxt[cur][bit] = cnt
        cur = nxt[cur][bit]
    num[cur] = n
def find_max(x):
    cur = 1
    for i in range(MAXBIT, -1, -1):
        bit = (x >> i) & 1
        if nxt[cur][bit ^ 1]:
            cur = nxt[cur][bit ^ 1]
        else:
            cur = nxt[cur][bit]
    return x ^ num[cur]

可撤销模板

cpp
int nxt[(int)3e5+10][2][2];
int cnt=0;
void insert(int v){
    int cur=0;
    for(int i=30;i>=0;i--){
        int p=(v>>i)&1;
        if(!nxt[cur][p][0])nxt[cur][p][0]=++cnt;
        nxt[cur][p][1]++;
        cur=nxt[cur][p][0];
    }
}
void del(int v){
    int cur=0;
    for(int i=30;i>=0;i--){
        int p=(v>>i)&1;
        nxt[cur][p][1]--;
        cur=nxt[cur][p][0];
    }
}
int get(int v){
    int cur=0,val=0;
    for(int i=30;i>=0;i--){
        int p=(v>>i)&1;
        if(nxt[cur][p^1][1]>0){
            cur=nxt[cur][p^1][0];
            val+=1<<i;
            continue;
        }
        cur=nxt[cur][p][0];
    }
    return val;
}

网站基于vitepress主题open17💙