3172: [Tjoi2013]单词

3172: [Tjoi2013]单词

Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 2783 Solved: 1322
[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

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
using namespace std;
#define LL long long
int read()
{
	int s=0,f=1;char ch=getchar();
	while(!('0'<=ch&&ch<='9')){if(ch=='-')f=-1;ch=getchar();}
	while('0'<=ch&&ch<='9'){s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
	return s*f;
}
int n,np;
int ch[1000006][26],fail[1000006];
char z[1000006];
queue<int>q;
int siz[1000006];
int bfn[1000006];
int end[205];
int main()
{
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	n=read();
	for(int i=1;i<=n;i++)
	   {scanf("%s",z+1);
	    int l=strlen(z+1),x=0;
	    for(int j=1;j<=l;j++)
	       {if(!ch[x][z[j]-'a'])
	            ch[x][z[j]-'a']=++np;
	        x=ch[x][z[j]-'a'];
	        siz[x]++;
		   }
		end[i]=x;
	   }
	for(q.push(0);!q.empty();)
	   {int u=q.front();q.pop();
	    bfn[++bfn[0]]=u;
	    for(int i=0;i<26;i++)
	       {int &v=ch[u][i];
		    if(!v)
		       {v=ch[fail[u]][i];
			    continue;
			   }
			if(u)fail[v]=ch[fail[u]][i];
			q.push(v);
		   }
	   }
	for(int i=bfn[0];i;i--)
	    siz[fail[bfn[i]]]+=siz[bfn[i]];
	for(int i=1;i<=n;i++)
	    printf("%d\n",siz[end[i]]);
	//fclose(stdin);
	//fclose(stdout);
	return 0;
}

posted on 2016-06-13 21:52  wuyuhan  阅读(...)  评论(...编辑  收藏

导航