hdu 2222 Keywords Search
Keywords Search
给出n个单词和一个句子,问有多少单词在句子中出现过
#include<iostream> #include<cstdio> #include<cstring> #define N 500010 #define M 1000010 using namespace std; int a[N][26],word[N],fail[N],mark[N],q[N],n,size; char ch[M]; void insert(){ int len=strlen(ch),now=1; for(int i=0;i<len;i++){ int t=ch[i]-'a'; if(!a[now][t])a[now][t]=++size; now=a[now][t]; } word[now]++; } void acmach(){ int h=0,t=1; q[1]=1;fail[1]=0; while(h<t){ int now=q[++h]; for(int i=0;i<=25;i++){ if(!a[now][i])continue; int k=fail[now]; while(!a[k][i]) k=fail[k]; fail[a[now][i]]=a[k][i]; q[++t]=a[now][i]; } } } void solve(){ int len=strlen(ch),k=1,ans=0; for(int i=0;i<len;i++){ mark[k]=1; int t=ch[i]-'a'; while(!a[k][t])k=fail[k]; k=a[k][t]; if(mark[k])continue; for(int j=k;j;j=fail[j]){ ans+=word[j]; word[j]=0; } } printf("%d\n",ans); } int main(){ freopen("Cola.txt","r",stdin); int T;scanf("%d",&T); while(T--){ memset(a,0,sizeof(a)); memset(fail,0,sizeof(fail)); memset(word,0,sizeof(word)); memset(mark,0,sizeof(mark)); size=1; for(int i=0;i<=25;i++)a[0][i]=1;//为什么要这样预处理 scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%s",ch); insert(); } acmach(); scanf("%s",ch); solve(); } return 0; }