hdu 2896 AC自动机模板题
题意:给出n个模式串,再给出m个文本串
针对每一个文本串,假如文本串中包含模式串,就total++,然后输出包含的模式串,从小到达输出编号
思路:这道题有个地方需要注意一下,题目中给出的字符不单单只有小写字母,所以我们把trie的第二维开到128
其他地方没什么不同
但是! 我自我感觉这样子做是会超时的,可是竟然没有超。。。
根据数据:每一个文本串1e4,那么查询当个的复杂度为 1e4+模式串个数(这里忽略不计)*(模式串的平均长度,我们假定100)
因此,单个查询复杂度就已经到达了1e6,然后有1000个查询。。。
大概是学艺不精把,毕竟初学ac自动机,所以其中缘由并不清楚
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1000001; 4 struct AC{ 5 int son[130]; 6 int flag,fail; 7 }trie[maxn]; 8 int n,cnt; 9 char s[maxn]; 10 queue<int>q; 11 int total; 12 int match[maxn]; 13 int res[maxn]; 14 int book; 15 void Insert(char* s,int base) 16 { 17 int u=1,len=strlen(s); 18 for(int i=0;i<len;i++){ 19 int v=s[i]; 20 if(!trie[u].son[v]) 21 trie[u].son[v]=++cnt; 22 u=trie[u].son[v]; 23 } 24 trie[u].flag++; 25 match[u]=base; 26 } 27 void getFail() 28 { 29 for(int i=0;i<=128;i++) 30 trie[0].son[i]=1; //初始化0的所有儿子都是1 31 q.push(1);trie[1].fail=0; //将根压入队列 32 while(!q.empty()){ 33 int u=q.front();q.pop(); 34 for(int i=0;i<=128;i++){ //遍历所有儿子 35 int v=trie[u].son[i]; //处理u的i儿子的fail,这样就可以不用记父亲了 36 int Fail=trie[u].fail; //就是fafail,trie[Fail].son[i]就是和v值相同的点 37 if(!v){ 38 trie[u].son[i]=trie[Fail].son[i]; 39 continue; 40 } //不存在该节点,第二种情况 41 trie[v].fail=trie[Fail].son[i]; //第三种情况,直接指就可以了 42 q.push(v); //存在实节点才压入队列 43 } 44 } 45 } 46 int query(char* s) 47 { 48 int u=1,ans=0,len=strlen(s); 49 for(int i=0;i<len;i++){ 50 int v=s[i]; 51 int k=trie[u].son[v]; //跳Fail 52 while(k>1){ //经过就不统计了 53 if(trie[k].flag>0){ 54 book++; 55 res[book]=match[k]; 56 } 57 k=trie[k].fail; //继续跳Fail 58 } 59 u=trie[u].son[v]; //到下一个儿子 60 } 61 return ans; 62 } 63 int main(){ 64 cnt=1;scanf("%d",&n); 65 for(int i=1;i<=n;i++){ 66 scanf("%s",s); 67 Insert(s,i); 68 } 69 getFail(); 70 int T; 71 scanf("%d",&T); 72 for(int Case=1;Case<=T;Case++){ 73 book=0; 74 scanf("%s",s); 75 query(s); 76 if(book) total++; 77 sort(res+1,res+1+book); 78 if(book){ 79 printf("web %d: ",Case); 80 for(int i=1;i<book;i++) 81 printf("%d ",res[i]); 82 printf("%d\n",res[book]); 83 } 84 } 85 printf("total: %d\n",total); 86 return 0; 87 }