hdu 2222 史上最裸 AC自动机
来源:互联网 发布:海淘转运系统源码 编辑:程序博客网 时间:2024/06/05 18:05
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#include<queue>#include<set>using namespace std;const int maxn=52;const int maxm=1000002;char s[maxm],str[maxn];int t,n,m,ans,res;struct node{ int idx,flag; node *fail; node *next[27]; node() { memset(next,0,sizeof(next)); idx=0; flag=0; fail=NULL; }};void Insert(node *rt,char s[]){ node *p=rt; int i=0; while(s[i]) { int k=s[i++]-'a'; if(p->next[k]==NULL)p->next[k]=new node(); p=p->next[k]; } p->flag=1;//字符串结尾 p->idx++;//代表第几个字符串}void build_AC(node *rt){ int i,j=0; queue<node*>q; rt->fail=NULL; q.push(rt); while(!q.empty()) { node *p=q.front(); q.pop(); for(i=0;i<26;i++) { if(p->next[i]!=NULL)//寻找当前子树的失败指针 { if(p==rt) { p->next[i]->fail=rt; }else { node *tmp=p->fail; while(tmp!=NULL) { if(tmp->next[i]!=NULL)//找到失败指针 { p->next[i]->fail=tmp->next[i]; break; } tmp=tmp->fail; } if(tmp==NULL)p->next[i]->fail=rt;//无法获取,当前子树的失败指针为根 } q.push(p->next[i]); } } }}int query_AC(node *rt,char s[]){ int i=0,j; ans=0; node *p=rt; while(s[i]) { int k=s[i++]-'a'; while(p->next[k]==NULL&&p!=rt)p=p->fail;//失配 p=p->next[k]; if(p==NULL)p=rt;//失配指针为根 node *tmp=p; while(tmp!=rt&&tmp->idx>0) { ans+=tmp->idx; tmp->idx=-1; tmp=tmp->fail; } } return ans;}int main(){ cin>>t; while(t--) { cin>>n; int i,j; node *rt=new node(); for(i=1; i<=n; i++) { scanf("%s",&str); Insert(rt,str); } build_AC(rt); scanf("%s",s); int res=query_AC(rt,s); cout<<res<<endl; } return 0;}