标签:ash 启发式 相同 子串 问题 集合 注意 现在 lin
CF #476 E
题意:给你N(\(\leq 10^5\))个两两不同字符串,总长\(\leq 10^5\)。对于每一个字符串要保留一个非空前缀,使得得到的字符串依旧两两不同。求最终字符串总长最小可以是多少。
题解:看上去很经典的样子?开始先头脑风暴了一个傻逼贪心:按长度递增排序,每次贪心地把当前串取极短的前缀。果不其然地WA了。
考虑转化模型。如果建出了AC自动机,问题就转化成了:某些点上有关键点;现在可以把一个关键点移动到它的某个空祖先;求最终所有点深度和的最小值。无脑上了一个启发式合并套贪心:如果当前节点为空,直接挑深度最大的那个移动上来。或许有线性做法吧。
CF #475 D
题意:给你一个长度为\(N\)的字符串\(S\)。有\(Q\)个询问,每次给出\((str,k)\),要寻找一个\(S\)的子串\(S‘\),使得\(str\)在\(S‘\)里至少出现了\(k\)次。求\(S‘\)的最小可能长度。保证每个询问的\(str\)是不同的。\(N,Q,\sum len_{str} \leq 10^5\)
题解:这个idea比较老吧。直接考虑后缀自动机的right集合,大概是这么个模型:每次数轴上有\(M\)个点,询问编号差为\(k\)的两个点的距离的最小值。\(k\)是不定的,所以这个应该是不能维护的。
然后就只能考虑分块了。显然,如果一个询问比较长,我们就可以暴力\(O(N)\)扫整个串,这样怎么做都行;最经济的是直接套一个KMP,常数很小。
考虑短串怎么做。有一个经典的做法:每次枚举一种询问串的长度,然后把S中的每一个这样的位置hash,显然hash一样要并在一起。注意,此题保证询问的\(str\)互不相同,所以对于一个询问的这个hash值,我们是可以暴力扫描它所有hash与它相等的位置的。这样直接for一下就可以求出编号差为k的两个点的距离的最小值。
标签:ash 启发式 相同 子串 问题 集合 注意 现在 lin
原文地址:https://www.cnblogs.com/jiangshibiao/p/8955409.html