码迷,mamicode.com
首页 > 其他好文 > 详细

[Bzoj3172][Tjoi2013]单词(fail树)

时间:2018-04-13 22:35:16      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:ring   bzoj3172   print   content   desc   http   为什么   color   oid   

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树)

标签:ring   bzoj3172   print   content   desc   http   为什么   color   oid   

原文地址:https://www.cnblogs.com/lzdhydzzh/p/8824027.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!