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:

过于抽象,所以进行一个手写

posted @ 2024-09-29 11:43  daydreamer_zcxnb  阅读(11)  评论(0编辑  收藏  举报