inlinevoidinsert(constchar *s){ registerint len = strlen(s), index; Node *p = root; ::maxLen = std::max(::maxLen, len); for (registerint i = 0; i < len; i++) { index = s[i] - 'a'; if (!p->next[index]) p->next[index] = cur++; p->f[index] = 1, p = p->next[index]; } }
long f[MAXM][MAXM * MAXN];
inlinevoidbuild(){ Node *p, *next; std::queue<Node *> q; q.push(root); while (!q.empty()) { p = q.front(), q.pop(); for (registerint i = 0; i < 26; i++) { if (p->next[i]) { next = p->fail; while (next && !next->next[i]) next = next->fail; p->next[i]->fail = (next ? next->next[i] : root); p->next[i]->deep = p->deep + 1, q.push(p->next[i]); } } for (registerint i = 0; i < 26; i++) { if (!p->next[i]) { next = p; while (next && !next->next[i]) next = next->fail; p->next[i] = (next ? next->next[i] : root); } } } }
inlinevoidquery(){ long ans = 0; for (Node *p = pool + 1; p != cur; p++) if (p->fail != root) ans++; for (Node *p = pool + 1; p != cur; p++) { for (registerint i = 0; i < 26; i++) { if (!p->f[i] && p->next[i] != root) { f[1][p->next[i] - pool]++; } } } for (registerint i = 1; i <= maxLen; i++) { for (registerint j = 1; j < cur - pool; j++) { if (f[i][j]) { ans += f[i][j]; Node *now = pool + j; for (registerint k = 0; k < 26; k++) { if (now->f[k] || now->next[k]->deep >= i + 1) f[i + 1][now->next[k] - pool] += f[i][j]; } } } } std::cout << ans; }