题意:问前面给的全部串在最后一个串出现的次数
思路:这道题是AC自己主动机入门必做的题。所以没什么好说的,是个模版题,推荐一个大神写的算法具体解释。不懂得能够看一看。反正我是看他的稍稍懂了点
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; const int inf=0x3f3f3f3f; const int maxn=500010; const int N=26; struct node{ node *fail; node *next[N]; int num; node(){ fail=NULL; num=0; memset(next,NULL,sizeof(next)); } }*q[maxn]; char str1[60],str2[1000010]; int head,tail; void insert_Trie(char *str,node *root){ node *p=root; int i=0; while(str[i]){ int id=str[i]-'a'; if(p->next[id]==NULL) p->next[id]=new node(); p=p->next[id];i++; } p->num++; } void build_ac(node *root){ root->fail=NULL; q[head++]=root; while(head!=tail){ node *temp=q[tail++]; node *p=NULL; for(int i=0;i<N;i++){ if(temp->next[i]!=NULL){ if(temp==root) temp->next[i]->fail=root; else{ p=temp->fail; while(p!=NULL){ if(p->next[i]!=NULL){ temp->next[i]->fail=p->next[i]; break; } p=p->fail; } if(p==NULL) temp->next[i]->fail=root; } q[head++]=temp->next[i]; } } } } int query(node *root){ int i=0,ans=0; node *p=root; while(str2[i]){ int id=str2[i]-'a'; while(p->next[id]==NULL&&p!=root) p=p->fail; p=p->next[id]; p=(p==NULL)?root:p; node *temp=p; while(temp!=root&&temp->num!=-1){ ans+=temp->num; temp->num=-1; temp=temp->fail; } i++; } return ans; } int main(){ int T,n; scanf("%d",&T); while(T--){ node *root=new node(); head=tail=0; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%s",str1); insert_Trie(str1,root); } build_ac(root); scanf("%s",str2); int ans=query(root); printf("%d ",ans); } return 0; }
点击打开链接