2017.9.22. 字典树

来源:互联网 发布:2017淘宝违规考试答案 编辑:程序博客网 时间:2024/06/05 02:47

字典树

样题:

单词的安全性
题目描述
我们这样定义一组单词的安全性:当且仅当不存在一个单词是另一个单词的前缀。这样才能保证数据不容易被误解。
现在你手上有一个单词集合 S ,你需要计算有多少个子集是安全的。注意空集永远是安全的。

输入格式
第 1 行一个整数 n ,表示集合的大小,以下 n 行,每行一个 “a” … “z” 构成的字符串。

输出格式
一个数表示安全子集的个数。

样例数据 1
输入  [复制]

3
hello
hell
hi
输出

6
备注
【数据范围】
对于 30% 的数据,满足:1≤n≤10;
对于 100% 的数据,满足:1≤n≤50;字符串长度≤50;没有两个字符串完全相同。

std.cpp:

#include<iostream>#include<iomanip>#include<cstdio>#include<cstdlib>#include<cstdio>#include<cstring>#include<string>#include<cmath>#include<algorithm>#include<queue>using namespace std;const int kkk=60;struct node{int cnt,son[26];}tr[kkk*kkk];int n,cnt=0;long long f[kkk*kkk];char s[kkk];void update(){    int len=strlen(s),u=0;    for(int i=0;i<len;i++)    {        if(!tr[u].son[s[i]-'a'])tr[u].son[s[i]-'a'] = ++cnt;        u = tr[u].son[s[i]-'a'];    }    tr[u].cnt++;}void dfs(int u){    f[u]=1;    for(int i=0;i<26;i++)      if(tr[u].son[i])      {        dfs(tr[u].son[i]);        f[u] = 1ll*f[u]*f[tr[u].son[i]];      }    if(tr[u].cnt)f[u]++;}int main(){    cin >> n;    while(n--){cin >> s; update();}    dfs(0);    cout << f[0];}
原创粉丝点击