AC自动机(指针查找是否存在)
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 using namespace std; 8 const int maxn = 1000000+10; 9 const int n = 26; 10 char y[maxn]; 11 int result=0; 12 13 struct Trie 14 { 15 Trie *next[n]; 16 int count1; 17 Trie *fail; 18 Trie() 19 { 20 fail=NULL; 21 count1=0; 22 for(int i=0;i<n;i++) 23 next[i]=NULL; 24 } 25 }; 26 27 Trie *root; 28 29 void buildTrie(char *str) 30 { 31 int len=strlen(str); 32 Trie *p=root,*q; 33 for(int i=0;i<len;i++) 34 { 35 int id=str[i]-'a'; 36 if(p->next[id]==NULL) 37 p->next[id]=new Trie(); 38 p=p->next[id]; 39 } 40 p->count1++; 41 } 42 43 void buildfail() 44 { 45 queue<Trie* > q; 46 q.push(root); 47 while(!q.empty()) 48 { 49 Trie *p=q.front();q.pop(); 50 for(int i=0;i<n;i++) 51 { 52 if(p->next[i]!=NULL) 53 { 54 if(p==root) p->next[i]->fail=root; 55 else{ 56 Trie *temp=p->fail; 57 while(temp!=NULL){ 58 if(temp->next[i]!=NULL){ 59 p->next[i]->fail=temp->next[i]; 60 break; 61 } 62 if(temp->next[i]==NULL) 63 temp=temp->fail; 64 } 65 if(temp==NULL) 66 p->next[i]->fail=root; 67 } 68 q.push(p->next[i]); 69 } 70 } 71 } 72 } 73 74 int query(char *str) 75 { 76 int len = strlen(str); 77 Trie *p=root; 78 for(int i=0;i<len;i++) 79 { 80 int id=str[i]-'a'; 81 while(p->next[id]==NULL&&p!=root) 82 p=p->fail; 83 p=p->next[id]; 84 if(p==NULL) 85 p=root; 86 Trie *temp=p; 87 while(temp!=root&&temp->count1!=-1)//扫后缀 88 { 89 result+=temp->count1; 90 temp->count1=-1; 91 temp=temp->fail; 92 } 93 } 94 return result; 95 } 96 97 int main() 98 { 99 int case1; 100 scanf("%d",&case1); 101 while(case1--) 102 { 103 result=0; 104 int n; 105 scanf("%d",&n); 106 root=new Trie(); 107 while(n--) 108 { 109 char s[60]; 110 scanf("%s",s); 111 buildTrie(s); 112 } 113 buildfail(); 114 scanf("%s",y); 115 printf("%d\n",query(y)); 116 } 117 return 0; 118 }