Good Article Good sentence
\[ Time Limit: 3000 ms\quad Memory Limit: 32768 kB \]
题意
给出一个 \(S\) 串,在给出 \(n\) 个 \(T\) 串,求出 \(S\) 串中有多少子串没有在任意一个 \(T\) 串中出现过
思路
\(\quad\) 首先可以对 \(S\) 串构建后缀自动机,然后在插入 \(n\) 个 \(T\) 串,每两个串之间用 \(27\) 隔开,然后可以求出这个自动机上每个节点出现的最左位置 \(left\) 和最右位置 \(right\),然后判断 \(right\) 在 \(Slen\) 内时,这个节点包含的子串就是一个答案!但是!\(MLE\) 了,哭了?,所以我也不知道这个做法能不能过,应该可以。
\(\quad\) 正确的做法,先对
\(S\) 串构建后缀自动机,结构体内多开一个变量
\(maxlen\) 表示在
\(i\) 个节点上,和任意一个
\(T\) 串的最长连续公共子串,可以枚举
\(T\) 串,每一个
\(T\) 串用与
\(SPOJ-LCS\) 类似的做法来做。在注意一下子串往
\(father\) 更新的过程,原理与
\(SPOJ-LCS2\) 类似。
\(\quad\) 求出每个节点的
\(maxlen\) 后,就可以开始计算答案了,可以分成两种情况:
- maxlen = 0,这个节点内的所有子串都满足条件,满足条件的子串有 \(node[i].len - node[father].len\) 个。
- 长度在 [maxlen+1,node[i].len] 区间内的子串满足条件,满足条件的子串有 \(node[i].len - maxlen\) 个。
#include