Trie字典树
BZOJ 1174 [Balkan2007]Toponyms
给你一个字符集合,你从其中找出一些字符串出来. 希望你找出来的这些字符串的最长公共前缀*字符串的总个数最大化.
(N≤1000000)
字符串长度不大于(20000)
保证输入文件不大于(10M)
建一棵字典树,对每个结点维护tag表示当前节点的子树中有多少个单词,然后寻找深度*tag的最大值
POJ 2001 Shortest Prefixes
字符串的前缀是从给定字符串的开头开始的子字符串。(“carbon”)的前缀是:(“c”、“ca”、“car”、“carb”、“carbo”)和(“carbon”)。注意,在这个问题中,空字符串不被视为前缀,但是每个非空字符串都被视为自身的前缀。在日常语言中,我们倾向于用前缀来缩写单词。例如,(“carbohydrate”)通常缩写为(“carb”)。在这个问题中,给定一组单词,您将为每个单词找到唯一标识其所代表的单词的最短前缀。
在下面的示例输入中,(“carbohydrate”)可以缩写为(“carboh”),但不能缩写为(“carbo”)(或任何更短的词),因为列表中还有其他以(“carbo”)开头的单词。
完全匹配将覆盖前缀匹配。例如,前缀(“car”)与给定的单词(“car”)完全匹配。因此,可以毫不含糊地理解,(“car”)是(“car”)的缩写,而不是(“carry”)或列表中以(“car”)开头的任何其他词。
听说这是模板题???
全部插入tire树中,对每个结点维护tag表示当前节点的子树中有多少个单词,挨个查找字符串,查到一个tag为1的前缀,即为最短前缀
BZOJ 1954
给定一棵(n)个点的带权树,求树上最长的异或和路径
(dfs)求出每个点到根的路径,(n)个数,求两两之间的最大异或和是多少
将(n)个数插入一个(01tire)中,然后在字典树下查找每个数的最大异或和(从高位到低位尽量往与这个数字的二进制位相反的地方走);
Luogu 3065
(Bessie)一直在研究字符串。她发现,通过改变字母表的顺序,她可以按改变后的字母表来排列字符串(字典序大小排列)。
例如,(Bessie)发现,对于字符串串“(omm)”,“(moo)”,“(mom)”和“(ommnom)”,她可以使用标准字母表使“(mom)”排在第一个(即字典序最小),她也可以使用字母表“(abcdefghijklonmpqrstuvwxyz)”使得“(omm)”排在第一个。然而,(Bessie)想不出任何方法(改变字母表顺序)使得“(moo)”或“(ommnom)”排在第一个。
接下来让我们通过重新排列字母表的顺序来计算输入中有哪些字符串可以排在第一个(即字典序最小),从而帮助(Bessie)。
要计算字符串(X)和字符串(Y)按照重新排列过的字母表顺序来排列的顺序,先找到它们第一个不同的字母(X[i])与(Y[i]),按重排后的字母表顺序比较,若(X[i])比(Y[i])先,则(X)的字典序比(Y)小,即(X)排在(Y)前;若没有不同的字母,则比较(X)与(Y)长度,若(X)比(Y)短,则(X)的字典序比(Y)小,即(X)排在(Y)前。
(N≤30000),字符串总长不会超过(300000)
将所有字符串加入(tire)中,对于字符串(s),假设它可以排在第一位,那么它的字符(x)的优先级一定大于和他相同父节点的优先级,然后连边拓扑判环,有环则证明不能