2.4字典树
算法理解
将一个字符串的每一位对应一个深度,每个字符对应一个节点,有一堆这样的字符串于是就构成了一棵树
如何存储树呢?
如果按照树的大小开点,有n层,一共要开 \(26^n\) 个点,一定是不行的,考虑一种类似于链表的思想,如果要开一个点,就进行编号,然后对应26条边分别存下一位的标号,注意要开 \(tr[N*26][26]\)个点,因为一共有n个字符串,n个字符串每一位都有可能不同
T1:
每遍历一个点就把它依次经过的点加1,然后统计要查询的字符串最后一个字符上对应的点权
T2:
经典字典树,我们将点转化为二进制,然后考虑,对于两个数,它们出现不同的位数越高,异或值越大,倒序将每一个数二进制存入,枚举一个数,然后遍历树,只要有和枚举数不同的叉就分,最后统计最大值
T3:
跑一边dfs统计一个节点到根的异或值 \(s[i]\) ,然后只要求出最大的 \(s[i] xor s[j]\),就行了,但你会发现如果i,j在一个子树內,lca(i,j)到根节点的异或值会统计两次,但别忘了,一个数异或上本身的答案就是0
T4:
比较板子的一题,每一篇文章建一棵字典树,注意,有一个坑点,就是如果单纯查询此字符串是否存在在字典树中会wa,因为可能这个字符串是某个单词的前缀
T5:
有坑,数据范围应该是5e4,给小了,还得我先打了一个暴力先re然后又tle了,后来才知道上当了
题解两个思路,一是枚举每一个字符串的断点,然后判断前后坠是否都出现过
二是,正反建字典树,将前后缀完全由别的字符串构成的点标记下来,然后判断能否拼接上
T6:
就是把一个串经过的点都加一遍,访问到只有一标记的点就输出,注意 \(tr[r][id]\)存的是r经过id这条边到达下一个点的编号
T7:
建树后手动模拟一下发现规律即可
注:走右移运算中,答案类型看左边的数的类型,1默认是一个int范围常数,要想改成long long要用1ll
T8:
存一下每个串经过点的编号,然后预处理出最大间隔,查询时调用即可
T9:
过于抽象,所以进行一个手写