voidinsert(int rt, char *s){ int l = strlen(s), now = rt; for (int i = 0; i < l; ++i) { if (!T[now].nxt[ch]) T[now].nxt[ch] = ++top; now = T[now].nxt[ch]; } ++T[now].cnt; }
voidinit_fail(int rt){ queue<int> Q; for (int i = 0; i < 26; ++i) { int u = T[rt].nxt[i]; if (!u) { T[rt].Nxt[i] = rt; continue; } T[rt].Nxt[i] = u; T[u].Cnt = T[u].cnt; T[u].fail = rt; Q.push(u); } while (!Q.empty()) { int u = Q.front(); Q.pop(); for (int i = 0; i < 26; ++i) { int v = T[u].nxt[i]; if (!v) { T[u].Nxt[i] = T[T[u].fail].Nxt[i]; continue; } T[u].Nxt[i] = v; T[v].fail = T[T[u].fail].Nxt[i]; T[v].Cnt = T[v].cnt + T[T[v].fail].Cnt; Q.push(v); } } }
intquery(char *s){ int l = strlen(s), ans = 0; for (int o = 1; o <= num; ++o) for (int i = 0, now = rt[o]; i < l; ++i) now = T[now].Nxt[ch], ans += T[now].Cnt; return ans; }
voidmerge(int &i, int j){ if (!i) return i = j, void(); if (!j) return ; T[i].cnt += T[j].cnt; for (int o = 0; o < 26; ++o) merge(T[i].nxt[o], T[j].nxt[o]); }