struct Node { int next[26]; int par, int fail; bool isfin = false; Node(){fail = 0; fors(i, 0, 25) next[i] = -1;} }; Node trie[N]; int c; void insert(char s[], int i, int node) { if(s[i] == '\0') { trie[node].isfin = true; return; } if(trie[node].next[s[i]-'a'] == -1) { trie[node].next[s[i]-'a'] = ++c; trie[c].par = node; } insert(s, i+1, trie[node].next[s[i]-'a']); } void bfs() { queue q; q.push({0, -1}); while(!q.empty()) { auto [node, x] = q.front(); q.pop(); if(x != -1) { int pf = trie[trie[node].par].fail; while(pf != 0 and trie[pf].next[x] == -1) pf = trie[pf].fail; if(trie[node].par != 0 and trie[pf].next[x] != -1) { trie[node].fail = trie[pf].next[x]; trie[node].isfin |= trie[trie[pf].next[x]].isfin; } else trie[node].fail = 0; } fors(i, 0, 25) { if(trie[node].next[i] == -1) continue; q.push({trie[node].next[s[i]-'a'], i}); } } } // For char* s, insert(s+1, 0, 0); // trie[0].fail = 0; bfs(); // find trie from s: int now = 0, ok = false; for(int i = 0; s[i]; i++) { while(now != 0 and trie[now].next[s[i]-'a'] == -1) now = trie[now].fail; if(trie[now].next[s[i]-'a'] != -1) { now = trie[now].next[s[i]-'a']; if(trie[now].isfin) ok = true; } }