某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。
某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。
第一个一个整数N,表示有多少个单词,接下来N行每行一个单词。每个单词由小写字母组成,N<=200,单词长度不超过10^6
输出N个整数,第i行的数字表示第i个单词在文章中出现了多少次。
#include <cstdio> #include <cstring> #include <iostream> #include <queue> using namespace std; const int maxn=1000010; struct node { int fail,ch[26],sum; }p[maxn]; int n,m,tot; int Q[maxn],ans[maxn],pos[maxn]; char w[maxn]; queue<int> q; int main() { scanf("%d",&n); int i,j,k,u,t; tot=1; for(i=1;i<=n;i++) { scanf("%s",w); u=1; k=strlen(w); for(j=0;j<k;j++) { if(!p[u].ch[w[j]-‘a‘]) p[u].ch[w[j]-‘a‘]=++tot; u=p[u].ch[w[j]-‘a‘]; p[u].sum++; } pos[i]=u; } q.push(1); while(!q.empty()) { u=q.front(),q.pop(); Q[++Q[0]]=u; for(i=0;i<26;i++) { if(!p[u].ch[i]) continue; q.push(p[u].ch[i]); if(u==1) { p[p[u].ch[i]].fail=1; continue; } t=p[u].fail; while(!p[t].ch[i]&&t) t=p[t].fail; if(t) p[p[u].ch[i]].fail=p[t].ch[i]; else p[p[u].ch[i]].fail=1; } } for(i=tot;i>=2;i--) p[p[Q[i]].fail].sum+=p[Q[i]].sum; for(i=1;i<=n;i++) printf("%d\n",p[pos[i]].sum); return 0; }
原文:http://www.cnblogs.com/CQzhangyu/p/6252620.html