标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 25356 Accepted Submission(s): 8280
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <string> 7 #include <vector> 8 #include <stack> 9 #include <queue> 10 #include <set> 11 #include <map> 12 #include <iomanip> 13 #include <cstdlib> 14 using namespace std; 15 const int INF=0x5fffffff; 16 const int MS=10005; 17 const double EXP=1e-8; 18 19 struct node 20 { 21 int have;//根据情况灵活变化 22 node * next[26]; 23 }nodes[MS*50]; //注意这个大小 尽量大一点 24 25 node *root; 26 int cnt,ans; 27 28 char text[MS*100]; 29 30 node * add_node(int c) 31 { 32 node *p=&nodes[c]; 33 for(int i=0;i<26;i++) 34 p->next[i]=NULL; 35 p->have=0; 36 return p; 37 } 38 39 void insert(char *str) 40 { 41 node *p=root; 42 int len=strlen(str); 43 for(int i=0;i<len;i++) 44 { 45 int id=str[i]-‘a‘; 46 if(p->next[id]==NULL) 47 { 48 p->next[id]=add_node(cnt++); 49 } 50 p=p->next[id]; 51 } 52 p->have++; 53 } 54 void search(char *str) 55 { 56 node *p=root; 57 int len=strlen(str); 58 for(int i=0;i<len;i++) 59 { 60 int id=str[i]-‘a‘; 61 p=p->next[id]; 62 if(p==NULL) 63 return ; 64 if(p->have) 65 { 66 ans+=p->have; 67 p->have=0; 68 } 69 } 70 } 71 72 int main() 73 { 74 int n,i,T; 75 scanf("%d",&T); 76 while(T--) 77 { 78 cnt=0; 79 ans=0; 80 root=add_node(cnt++); 81 scanf("%d",&n); 82 for(i=0;i<n;i++) 83 { 84 scanf("%s",text); 85 insert(text); 86 } 87 scanf("%s",text); 88 int len=strlen(text); 89 for(i=0;i<len;i++) 90 { 91 search(text+i); 92 } 93 printf("%d\n",ans); 94 } 95 return 0; 96 }
这题是AC自动机最经典的入门题。学会了kmp,Trie,就可以学习ac自动机了。
time : 280 ms
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <string> 7 #include <vector> 8 #include <stack> 9 #include <queue> 10 #include <set> 11 #include <map> 12 #include <iomanip> 13 #include <cstdlib> 14 using namespace std; 15 const int INF=0x5fffffff; 16 const int MS=10005; 17 const double EXP=1e-8; 18 // AC自动机 KMP TRIE 19 struct node 20 { 21 bool isbad; 22 node *pre; 23 node * next[26]; 24 int n; 25 }nodes[MS*50]; //注意这个大小 个数*每个的长度就不会访问非法内存 26 27 node *root; 28 int cnt,ans; 29 30 char text[MS*100]; 31 32 node * add_node(int c) 33 { 34 node *p=&nodes[c]; 35 for(int i=0;i<26;i++) 36 p->next[i]=NULL; 37 p->isbad=false; 38 p->pre=NULL; 39 p->n=0; 40 return p; 41 } 42 43 void insert(char *str) 44 { 45 node *p=root+1; 46 int len=strlen(str); 47 for(int i=0;i<len;i++) 48 { 49 int id=str[i]-‘a‘; 50 if(p->next[id]==NULL) 51 { 52 p->next[id]=add_node(cnt++); 53 } 54 p=p->next[id]; 55 } 56 p->isbad=true; 57 p->n++; //终止节点为坏节点 58 } 59 60 void build() 61 { // 在trie树上加前缀指针 62 for(int i=0;i<26;i++) 63 root->next[i]=nodes+1; 64 root->pre=NULL; 65 nodes[1].pre=nodes; 66 deque<node *> dq; 67 dq.push_back(nodes+1); 68 while(!dq.empty()) 69 { 70 node *proot=dq.front(); 71 dq.pop_front(); 72 for(int i=0;i<26;i++) 73 { 74 node *p=proot->next[i]; 75 if(p!=NULL) 76 { 77 node *pre=proot->pre; 78 while(pre) 79 { 80 if(pre->next[i]!=NULL) //NULL==0 81 { 82 p->pre=pre->next[i]; 83 if(p->pre->isbad) 84 p->isbad=true; 85 break; 86 } 87 else 88 pre=pre->pre; 89 } 90 dq.push_back(p); 91 } 92 } 93 } 94 } 95 96 void search(char *str) 97 { //返回值为true,说明包含模式串 98 node *p=nodes+1; 99 int len=strlen(str); 100 for(int i=0;i<len;i++) 101 { 102 int id=str[i]-‘a‘; 103 while(p!=nodes+1&&p->next[id]==NULL) 104 { 105 p=p->pre; 106 } 107 p=p->next[id]; 108 if(p==NULL) 109 { 110 p=nodes+1; 111 } 112 node *tp=p; 113 while(tp!=nodes+1&&tp->n!=0) 114 { 115 ans+=tp->n; 116 tp->n=0; 117 tp=tp->pre; 118 } 119 120 /* 121 while(1) 是否包含模式串 122 { 123 if(p->next[id]) 124 { 125 p=p->next[id]; 126 if(p->isbad) 127 return true; 128 break; 129 } 130 else 131 p=p->pre; 132 } 133 */ 134 } 135 136 //return false; 137 } 138 139 int main() 140 { 141 int n,T; 142 scanf("%d",&T); 143 while(T--) 144 { 145 cnt=0; 146 ans=0; 147 root=add_node(cnt++); 148 add_node(cnt++); 149 scanf("%d",&n); 150 for(int i=0;i<n;i++) 151 { 152 scanf("%s",text); 153 insert(text); 154 } 155 build(); 156 scanf("%s",text); 157 search(text); 158 printf("%d\n",ans); 159 } 160 return 0; 161 }
标签:
原文地址:http://www.cnblogs.com/767355675hutaishi/p/4305845.html