【BZOJ3172】单词(AC自动机)

【BZOJ3172】单词(AC自动机)

题面

Description

某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。

Input

第一个一个整数N,表示有多少个单词,接下来N行每行一个单词。每个单词由小写字母组成,N<=200,单词长度不超过10^6

Output

输出N个整数,第i行的数字表示第i个单词在文章中出现了多少次。

Sample Input

3

a

aa

aaa

Sample Output

6

3

1

题解

yyb因为调这道题而死亡

在重复一下题目的意思把。。。
看不见文章对不读,,
那是因为文章就是所有单词组成的
然后你就可以yy所有单词中间有一个空格之类的东西

很明显的AC自动机,
然后,我们
每次把每个单词带进去匹配一下
暴跳fail指针
美滋滋的收获90分
yyb炸裂了

0分是空间玩炸了。。。

暴跳fail指针是可以被卡炸的。。。
所以,我们就不暴跳了呀
每次要跳的时候就在这个点这里打一个标记
所有标记打完之后
我们就从底下往上一层层跳(记一下bfs序倒着跳)
每次就只跳一层,然后标记丢到上面去
这样就可以一起跳啦

然后美滋滋的 AC啦

对了,
这题还有一点
就是会有重复的单词。。。
所以要记录一下每个单词和哪个单词是一样的(不是并查集)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 1100000
struct Node
{
	int vis[26];
	int fail,ff;
	int id,sum;
}t[MAX];
int tot,lid[500];
int ans[500];
int n,q[MAX],tp;
char ch[MAX],ss[MAX];
void Insert(int id,char *s)
{
	int gg=strlen(s);
	int now=0;
	for(int i=0;i<gg;++i)
	{
		if(!t[now].vis[s[i]-'a'])
			t[now].vis[s[i]-'a']=++tot;
		t[t[now].vis[s[i]-'a']].ff=now;
		now=t[now].vis[s[i]-'a'];
	}
	if(!t[now].id)t[now].id=id,lid[id]=id;
	else lid[id]=t[now].id;
}
queue<int> Q;
void GetFail()
{
	for(int i=0;i<26;++i)
		if(t[0].vis[i])
			Q.push(q[++tp]=t[0].vis[i]);
	while(!Q.empty())
	{
		int u=Q.front();Q.pop();
		for(int i=0;i<26;++i)
		{
			if(t[u].vis[i])
				t[t[u].vis[i]].fail=t[t[u].fail].vis[i],Q.push(q[++tp]=t[u].vis[i]);
			else
				t[u].vis[i]=t[t[u].fail].vis[i];
		}
	}
}
int l=0;
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;++i) 
	{
		scanf("%s",ch);
		Insert(i,ch);
		int len=strlen(ch);
		for(int j=0;j<len;++j)
			ss[l++]=ch[j];
		ss[l++]='#';
	}
	GetFail();
	int now=0;
	for(int j=0;j<l;++j)
	{
		if(ss[j]=='#')now=0;
		else now=t[now].vis[ss[j]-'a'];
		t[now].sum++;
	}
	for(int i=tp;i;i--)
	{
		ans[t[q[i]].id]+=t[q[i]].sum;
		t[t[q[i]].fail].sum+=t[q[i]].sum;
	}
	for(int i=1;i<=n;++i)printf("%d\n",ans[lid[i]]);
	return 0;
}

posted @ 2018-01-09 15:16  小蒟蒻yyb  阅读(377)  评论(0编辑  收藏  举报