您的位置:首页 > 其它

HDU - 2222 Keywords Search

2016-08-04 10:13 411 查看
题目传送门:23333

AC自动机的裸题(虽然我看了好长时间写了2H才2333的A掉QAQ)

开始没看到多组数据=幸好有cl大的提醒

参考:AC自动机详解

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define rep(j,k,l) for (int j=k;j<=l;j++)
#define N 10005
#define M 1000005

using namespace std;
int n,m,cnt,head,tail,ch[50*N][26],sum[50*N],fail[50*N],queue[50*N];
char s[M];

void add(){

int rt=0,len=strlen(s);
rep(i,0,len-1){

if (!ch[rt][s[i]-'a']) ch[rt][s[i]-'a']=++cnt;
rt=ch[rt][s[i]-'a'];

}
sum[rt]++;

}

void getfail(){

fail[0]=-1;head=0;tail=1;
while (head<tail){

int x=queue[++head];
rep(i,0,25) if (ch[x][i])
queue[++tail]=ch[x][i],
fail[ch[x][i]]=x==0?0:ch[fail[x]][i];
else ch[x][i]=x==0?0:ch[fail[x]][i];

}

}

int getans(){

int ans=0,len=strlen(s),rt=0;
rep(i,0,len-1){

rt=ch[rt][s[i]-'a'];
int k=rt;
while (k!=0){

ans+=sum[k];
sum[k]=0;
k=fail[k];

}

}
return ans;

}

int main(){

scanf("%d",&n);
while (n--){

memset(sum,0,sizeof(sum));
memset(ch,0,sizeof(ch));
scanf("%d",&m);
while (m--){

scanf("%s",s);
add();

}
getfail();
scanf("%s",s);
printf("%d\n",getans());

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: