第一道AC自动机的题,有纪念意义,由于省赛,先贴代码,解释神马的以后再说!!! #include<string.h> #include<stdio.h> #define N 1000010 #define M 500010 #define K 26 struct TrieNode{ TrieNode *fail; //失败指针 TrieNode *next[K]; //子接点 int count; //单词结束 TrieNode() { fail=NULL; count=0; memset(next,NULL,sizeof(next)); } }*q[M],*root; int head,tail; //头尾接点 char s[51],str[N];//单词,模式串 void TrieInsert() //构造Trie树 { int i=0,index; TrieNode *p=root; while(s[i]) { index=s[i]-'a'; if(p->next[index]==NULL){ p->next[index] = new TrieNode(); } p = p->next[index]; i++; } p->count++; } void Init() //初始化 { int n; head = tail=0; root = new TrieNode(); scanf("%d",&n); while(n--){ scanf("%s",s); TrieInsert(); } } void Build_ac_automation() //构建失败指针 { int i; TrieNode *p,*temp; q[head++]=root; root->fail=NULL; while(head!=tail){ p = q[tail++]; temp=NULL; for(i=0;i<K;i++){ if(p->next[i]!=NULL){ if(p==root){ p->next[i]->fail=root; } else { temp = p->fail; while(temp!=NULL){ if(temp->next[i]!=NULL){ p->next[i]->fail=temp->next[i]; break; } temp=temp->fail; } if(temp==NULL) p->next[i]->fail=root; } q[head++]=p->next[i]; } } } } int Solve() //查找单词 { int cnt=0,i=0,index,len=strlen(str); TrieNode *p=root,*temp; while(str[i]){ index =str[i]-'a'; while(p->next[index]==NULL && p!=root)p=p->fail; p=p->next[index]; p=(p==NULL)?root:p; temp=p; while(temp!=root &&temp->count!=-1) { cnt+=temp->count; temp->count=-1; temp=temp->fail; } i++; } return cnt; } int main() { int t; scanf("%d",&t); while(t--) { Init(); Build_ac_automation(); scanf("%s",str); printf("%d/n",Solve()); } return 0; }