int trie[MAXN * MAXS + 1][26], tot = 0; int end[MAXN * MAXS + 1], fail[MAXN * MAXS + 1]; int f[MAXM + 1][MAXN * MAXS + 1];
voidinsert(char *s){ int len = strlen(s), p = 0; for (int i = 0; i < len; i++) { if (!trie[p][s[i] - 'A']) trie[p][s[i] - 'A'] = ++tot; p = trie[p][s[i] - 'A']; } end[p]++; }
voidbuild(){ std::queue<int> q; for (int i = 0; i < 26; i++) { if (trie[0][i]) { q.push(trie[0][i]); } } while (!q.empty()) { int u = q.front(); q.pop(); for (int i = 0; i < 26; i++) { if (trie[u][i]) { fail[trie[u][i]] = trie[fail[u]][i]; end[trie[u][i]] += end[trie[fail[u]][i]]; q.push(trie[u][i]); } else trie[u][i] = trie[fail[u]][i]; } } }
intpow(int a, int b){ int ans = 1; for (; b; b >>= 1, a = a * a % MOD) if (b & 1) ans = ans * a % MOD; return ans; }