[一本通1700]PFS集合
作者:互联网
题目描述
有一种特殊的集合叫做PFS(Prefix Free Set)集合。
一个PFS集合由若干字符串构成,且不存在一个字符串是另一个字符串的前缀。空集也被看作是PFS集合。
例如 {\("hello"\)} 和 {\("hello", "goodbye", "giant", "hi"\)} 是PFS集合,但 {\("hello","hell"\)} 和{\("great","gig","g"\)} 不是。
现在给你一个集合,请你求出它的子集是PFS集合的子集个数,答案对\(9191\)取模。
输入
输入数据第一行一个整数\(n\),表示集合里元素的个数。
以下n行,每行一个非空字符串\(s\),仅包含小写英文字母,表示集合中的元素。数据保证不存在两个相同的字符串。
输出
输出一个正整数\(ans\),表示对\(9191\)取模后的答案。
输入样例
3
hello
hi
hell
输出样例
6
提示
输入输出样例解释
除了 {\("hell","hello"\)} 和 {\("hi","hello","hell"\)} 两种情况外,其余情况均是PFS集合。
数据规模
对于\(30%\)的数据,\(n≤20\);
对于\(100%\)的数据,\(1≤n≤50000\),字符串长度不大于\(50\)。
思路
\(f[i]+=f[ch[i][1]]\times f[ch[i][2]]\times \cdots\times f[ch[i][26]]\)
代码
#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;
}
标签:1700,int,一本,字符串,PFS,ans,集合,hello 来源: https://www.cnblogs.com/Icys/p/15130207.html