有一種特殊的集合叫作PFS(Prefix Free Set)集合。ios
一個PFS集合由若干字符串構成,且不存在一個字符串是另外一個字符串的前綴。空集也被看做是PFS集合。spa
例如 {\("hello"\)} 和 {\("hello", "goodbye", "giant", "hi"\)} 是PFS集合,但 {\("hello","hell"\)} 和{\("great","gig","g"\)} 不是。code
如今給你一個集合,請你求出它的子集是PFS集合的子集個數,答案對\(9191\)取模。字符串
輸入數據第一行一個整數\(n\),表示集合裏元素的個數。get
如下n行,每行一個非空字符串\(s\),僅包含小寫英文字母,表示集合中的元素。數據保證不存在兩個相同的字符串。string
輸出一個正整數\(ans\),表示對\(9191\)取模後的答案。io
3 hello hi hell
6
除了 {\("hell","hello"\)} 和 {\("hi","hello","hell"\)} 兩種狀況外,其他狀況均是PFS集合。class
對於\(30%\)的數據,\(n≤20\);
對於\(100%\)的數據,\(1≤n≤50000\),字符串長度不大於\(50\)。stream
\(f[i]+=f[ch[i][1]]\times f[ch[i][2]]\times \cdots\times f[ch[i][26]]\)im
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int N = 2500000 + 128; int to[N][26]; int p; int cnt[N]; int f[N]; void dfs(int u) { int ans = 1; for (int i = 0; i < 26; i++) if (to[u][i]) { dfs(to[u][i]); ans = ans * f[to[u][i]] % 9191; } f[u] = ans; if (cnt[u]) f[u]++; } static char str[50016]; int main() { int n; scanf(" %d", &n); getchar(); ++p; for (int i = 1; i <= n; i++) { scanf(" %s", str + 1); int len = strlen(str + 1); int now = 1; for (int i = 1; i <= len; i++) { if (to[now][str[i] - 'a'] == 0) to[now][str[i] - 'a'] = ++p; now = to[now][str[i] - 'a']; } cnt[now] = 1; } dfs(1); printf("%d", f[1] % 9191); return 0; }