首页 > 代码库 > BZOJ 3172: [Tjoi2013]单词 AC自动机
BZOJ 3172: [Tjoi2013]单词 AC自动机
3172: [Tjoi2013]单词
Description
某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。
Input
第一个一个整数N,表示有多少个单词,接下来N行每行一个单词。每个单词由小写字母组成,N<=200,单词长度不超过10^6
Output
输出N个整数,第i行的数字表示第i个单词在文章中出现了多少次。
Sample Input
3
a
aa
aaa
a
aa
aaa
Sample Output
6
3
1
3
1
HINT
入门
#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;const int N=1e6+10,mod=1e9+7,inf=2e9+10;int nex[N][27],head,tail,pos[N],cnt = 1,fail[N],sum[N],q[N],n;char a[N];void insert(char *s,int &x) { int now = 1, len = strlen(s); for(int i = 0; i < len; ++i) { int index = s[i] - ‘a‘; if(!nex[now][index]) nex[now][index] = ++cnt; now = nex[now][index]; sum[now]++; } x = now;}void build_fail() { head = 0,tail = 0; q[tail++] = 1; fail[1] = 0; while(head != tail) { int now = q[head++]; for(int i = 0; i < 26; ++i) { if(!nex[now][i]) continue; int p = fail[now]; while(!nex[p][i]) p = fail[p]; fail[nex[now][i]] = nex[p][i]; q[tail++] = nex[now][i]; } }}int main() { for(int i = 0; i < 26; ++i) nex[0][i] = 1; scanf("%d",&n); for(int i = 1; i <= n; ++i) { scanf("%s",a); insert(a,pos[i]); }//cout<<1<<endl; build_fail(); for(int i = tail-1; i >=0; --i) sum[fail[q[i]]] += sum[q[i]]; for(int i = 1; i <= n; ++i) cout<<sum[pos[i]]<<endl; return 0;}
BZOJ 3172: [Tjoi2013]单词 AC自动机
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。