【字符串】hdu5384

来源:互联网 发布:hadoop 数据存储 编辑:程序博客网 时间:2024/04/29 16:52

裸的ac自动机居然没有看出来。。。

于是乎手撕了一发,

话说果然还是不喜欢用模板,

这篇挂出来就当是以后自己ac自动机的写法了。

挺好看的。。。

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<algorithm>using namespace std;char s[200100],w_s[200100],tmp_s[200100];int q[200100],q_tail,q_head,s_tail,s_len[200100],tot;struct rec{int next[30];int fail,count;}tree[100100];void clear(int x){for (int i=1;i<=27;i++)tree[x].next[i]=-1;tree[x].count=0;tree[x].fail=0;}void insert(char a[]){int len=strlen(a);int i,j,now=0,tmp;for (int i=0;i<len;i++){tmp=a[i]-'a'+1;if (tree[now].next[tmp]==-1){tree[now].next[tmp]=++tot;clear(tot);}now=tree[now].next[tmp];}tree[now].count++;}void makefail(){int now,now_f;q_tail=q_head=0;for (int i=1;i<=26;i++)if (tree[0].next[i]!=-1){q[++q_tail]=tree[0].next[i]; }while (q_tail!=q_head){q_head++;now=q[q_head];for (int i=1;i<=26;i++){if (tree[now].next[i]!=-1){q_tail++;q[q_tail]=tree[now].next[i];now_f=tree[now].fail;while (now_f>0&&tree[now_f].next[i]==-1)now_f=tree[now_f].fail;if (tree[now_f].next[i]!=-1) now_f=tree[now_f].next[i];tree[tree[now].next[i]].fail=now_f; }}}}void ac_work(char a[],int len){int tmp=0,ans=0,p;for (int i=1;i<=len;i++){int now=a[i]-'a'+1;while (tmp>0&&tree[tmp].next[now]==-1) tmp=tree[tmp].fail;if (tree[tmp].next[now]!=-1){tmp=tree[tmp].next[now];p=tmp;while (p>0){ans+=tree[p].count;p=tree[p].fail;}} } printf("%d\n",ans);}int main(){freopen("test.in","r",stdin);freopen("test.out","w",stdout);int t,n,m;scanf("%d",&t);s_tail=0;while (t--){tot=0;clear(0);s_tail=0;scanf("%d%d",&n,&m);for (int i=1;i<=n;i++){scanf("%s",tmp_s);int tmp_len=strlen(tmp_s);s_len[i]=tmp_len;for (int j=1;j<=tmp_len;j++)s[s_tail+j]=tmp_s[j-1];s_tail+=tmp_len;}for (int i=1;i<=m;i++){scanf("%s",tmp_s);insert(tmp_s); }makefail();s_tail=1;for (int i=1;i<=n;i++){for (int j=s_tail;j<=s_tail+s_len[i]-1;j++)w_s[j-s_tail+1]=s[j];s_tail+=s_len[i];ac_work(w_s,s_len[i]); }} return 0; }

0 0
原创粉丝点击