集训Day12
快乐 快乐就完事了
今天把Trie树 / 可持久化Trie树搞了一下
Trie树可以维护区间最大异或和
具体就是区间异或和 -> 区间两个前缀异或和的异或
然后就变成了
"从n个数里找2个数,使他们异或起来最大"
怎么办呢
把串高位补0补成所有串一样长
然后从高到低建一颗$\sum$为2——只有'0'和'1'两个字符的Trie树
然后$O(n)$枚举第一个串
然后在Trie上跑一个贪心,从高到低,如果这一位是0就去找1,如果是1就去找0
这样就$O(nlogn)$完成了
“一个序列,找出一个区间,使他们的异或和最大,求这个最大的异或和”
如果是
“一个序列,多次询问,每次询问一个区间,找一个子区间使子区间异或和最大”
那就是在这个区间里建一棵Trie树,然后查
但每次建树是$O(n)$的,所以我们可以考虑像可持久化线段树一样建一个可持久化Trie树出来
可持久化Trie树满足性质,每次只会修改一条链,最多$logn$个点
于是我们可以在时间空间都是$O(nlog^2n)$的复杂度里完成这个操作
例题
bzoj3261
直接用可持久化Trie树模拟即可
bzoj5338
一棵树
1 x y 查询节点x的子树中与y异或结果的最大值
2 x y z 查询路径x到y上点与z异或结果最大值
对于1询问
对原树树剖一下
利用树剖编号建立可持久化Trie
即维护按编号顺序的前缀
对于询问2
每个结点建可持久化Trie维护该点到根的路径
u~v的路径利用差分
u的Trie+v的Trie-lca(u,v)的Trie-fa[lca(u,v)]的Trie
bzoj4260
用Trie求出前缀异或和以及后缀异或和,再求出前缀异或和以及后缀异或和中最大的,前后相加,求最大值