这一题在 AC 自动机中递推标记(是否可以出现这段前缀)时:
void build() {
queue<int> q;
q.push(0);
while (!q.empty()) {
int u = q.front();
if (flag[fail[u]]) flag[u] = true;
q.pop();
for (int i = 0; i < 26; i++) {
if (ch[u][i]) {
if (!u) fail[ch[u][i]] = 0;
else fail[ch[u][i]] = ch[fail[u]][i];
q.push(ch[u][i]);
} else if (u) {
ch[u][i] = ch[fail[u]][i];
}
}
}
}
注释的那一行严格来说应该是需要的。
它的意义就是对于字典数上的父亲(前缀)不能出现,那么它的儿子也都不能出现。
但是因为这一题的特殊性,我们是从前往后依次确认的,所以在跳 fail 过程中儿子也一定被 check 过。
我只是提醒一下如果别的题遇到需要标记,记得加上这一行。。。