[Bzoj3172][Tjoi2013]单词(fail树)
Posted lzdhydzzh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Bzoj3172][Tjoi2013]单词(fail树)相关的知识,希望对你有一定的参考价值。
3172: [Tjoi2013]单词
Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 4777 Solved: 2345
[Submit][Status][Discuss]
Description
某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。
Input
第一个一个整数N,表示有多少个单词,接下来N行每行一个单词。每个单词由小写字母组成,N<=200,单词长度不超过10^6
Output
输出N个整数,第i行的数字表示第i个单词在文章中出现了多少次。
Sample Input
3 a aa aaa
Sample Output
6 3 1
HINT
分析:
fail树裸题,为什么我一开始会分析成parent树。。
AC代码:
# include <cstdio> # include <cstring> # include <iostream> using namespace std; const int N = 1e6 + 12; int ch[N][26],cnt,fail[N],n,id[212],w[N];char str[N]; int insert(char s[]) { int p = 0,v,len = strlen(s); for(int i = 0;i < len;i++) { v = s[i] - ‘a‘; if(!ch[p][v])ch[p][v] = ++cnt; p = ch[p][v]; w[p]++; } return p; } int que[N]; void bfs_fail() { int h = 0,t = 0,u,g; for(int i = 0;i < 26;i++)if(ch[0][i])que[t++] = ch[0][i]; while(h != t) { u = que[h++]; for(int i = 0;i < 26;i++) { int &v = ch[u][i];g = ch[fail[u]][i]; if(!v){v = g;continue;} fail[que[t++] = v] = g; } } for(int i = h - 1;~i;i--)w[fail[que[i]]] += w[que[i]]; } int main() { scanf("%d",&n); for(int i = 1;i <= n;i++)scanf("%s",str),id[i] = insert(str); bfs_fail(); for(int i = 1;i <= n;i++)printf("%d\n",w[id[i]]); }
以上是关于[Bzoj3172][Tjoi2013]单词(fail树)的主要内容,如果未能解决你的问题,请参考以下文章