字典树小记

字典树小记

普通字典树

没什么好讲的

0-1 Trie

非常有用,经常用于异或相关的题目

求一个集合中两两异或的最大值

枚举集合中的一个数 \(x\),按位贪心,如果这一位有一个与 \(x\) 不同的,那么字典树上走这一边,否则走 \(x\) 的这一边。具体见代码

int solve(int x){int p = 1, o = 0, ans = 0;F_(i,30,0){int o = ((x>>i)&1);if (ch[p][!o]){p = ch[p][!o];ans += (1<<i); } else {p = ch[p][o];}}return ans;
}

求两个集合中各选一个数异或的最小值

可以枚举第一个集合的数,也可以一次 \(dfs\)

int query(int u,int v,int bit){int res = 2e9;if (trie[u][0]&&trie[v][0]) res = min(res,query(trie[u][0],trie[v][0],bit-1));if (trie[u][1]&&trie[v][1]) res = min(res,query(trie[u][1],trie[v][1],bit-1));if (res < 2e9) return res;if (trie[u][0]&&trie[v][1]) res = min(res,(1<<bit)|query(trie[u][0],trie[v][1],bit-1));if (trie[u][1]&&trie[v][0]) res = min(res,(1<<bit)|query(trie[u][1],trie[v][0],bit-1));if (res==2e9) res = 0;return res;
}

可持久化 0-1 Trie