标签:保存 那是 tar display get 世界 心路历程 gif 不同
Description
Input
Output
Sample Input
3 aaa bbb ccc 2 aaabbbccc bbaacc
Sample Output
web 1: 1 2 3 total: 1
题意:中文题意不翻译
思路:用ac自动机去保存子串对主串进行查询,然后输出结果即可。
心路历程:这个题可以说浪费了我大多数的时间,主要原因是模板用的不对,百度得到的链表模板几乎都进行了测试,结果大多数都是MLE。直到去学习了数组类型的模板,才避免了这个问题。不过不得不承认数组类型的模板是非常好用的。
数组类型模板:
1 struct trie 2 { 3 int next[maxn][100],fail[maxn],end[maxn]; 4 int root,L; 5 int newnode() 6 { 7 for(int i=0;i<100;i++) 8 next[L][i]=-1; 9 end[L++]=-1; 10 return L-1; 11 } 12 void init() 13 { 14 L=0; 15 root=newnode(); 16 } 17 void insert(char buf[],int id) 18 { 19 int len=strlen(buf); 20 int now=root; 21 for(int i=0;i<len;i++) 22 { 23 if(next[now][buf[i]-‘ ‘]==-1) 24 next[now][buf[i]-‘ ‘]=newnode(); 25 now=next[now][buf[i]-‘ ‘]; 26 } 27 end[now]=id; 28 } 29 void build() 30 { 31 queue<int>Q; 32 fail[root]=root; 33 for(int i=0;i<100;i++) 34 if(next[root][i]==-1) 35 next[root][i]=root; 36 else 37 { 38 fail[next[root][i]]=root; 39 Q.push(next[root][i]); 40 } 41 while(!Q.empty()) 42 { 43 int now=Q.front(); 44 Q.pop(); 45 for(int i=0;i<100;i++) 46 if(next[now][i]==-1) 47 next[now][i]=next[fail[now]][i]; 48 else 49 { 50 fail[next[now][i]]=next[fail[now]][i]; 51 Q.push(next[now][i]); 52 } 53 } 54 } 55 int query(char buf[],int id) 56 { 57 int res[4]; 58 bool mark[510]={0}; 59 int len=strlen(buf); 60 int now=root; 61 memset(res,0,sizeof(res)); 62 for(int i=0;i<len;i++) 63 { 64 now=next[now][buf[i]-‘ ‘]; 65 int tmp=now; 66 while(tmp!=root) 67 { 68 if(end[tmp]!=-1) 69 { 70 if(!mark[end[tmp]]) 71 { 72 res[++res[0]]=end[tmp]; 73 mark[end[tmp]]=1; 74 } 75 } 76 tmp=fail[tmp]; 77 } 78 } 79 if(res[0]) 80 { 81 printf("web %d: ",id); 82 sort(res+1,res+res[0]+1); 83 for(int i=1;i<=res[0];i++) 84 { 85 printf("%d%c",res[i],i==res[0]?‘\n‘:‘ ‘); 86 } 87 return 1; 88 } 89 return 0; 90 } 91 };
AC代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <queue> 6 #include <algorithm> 7 using namespace std; 8 const int maxn=200*500+5; 9 struct trie 10 { 11 int next[maxn][100],fail[maxn],end[maxn]; 12 int root,L; 13 int newnode() 14 { 15 for(int i=0;i<100;i++) 16 next[L][i]=-1; 17 end[L++]=-1; 18 return L-1; 19 } 20 void init() 21 { 22 L=0; 23 root=newnode(); 24 } 25 void insert(char buf[],int id) 26 { 27 int len=strlen(buf); 28 int now=root; 29 for(int i=0;i<len;i++) 30 { 31 if(next[now][buf[i]-‘ ‘]==-1) 32 next[now][buf[i]-‘ ‘]=newnode(); 33 now=next[now][buf[i]-‘ ‘]; 34 } 35 end[now]=id; 36 } 37 void build() 38 { 39 queue<int>Q; 40 fail[root]=root; 41 for(int i=0;i<100;i++) 42 if(next[root][i]==-1) 43 next[root][i]=root; 44 else 45 { 46 fail[next[root][i]]=root; 47 Q.push(next[root][i]); 48 } 49 while(!Q.empty()) 50 { 51 int now=Q.front(); 52 Q.pop(); 53 for(int i=0;i<100;i++) 54 if(next[now][i]==-1) 55 next[now][i]=next[fail[now]][i]; 56 else 57 { 58 fail[next[now][i]]=next[fail[now]][i]; 59 Q.push(next[now][i]); 60 } 61 } 62 } 63 int query(char buf[],int id) 64 { 65 int res[4]; 66 bool mark[510]={0}; 67 int len=strlen(buf); 68 int now=root; 69 memset(res,0,sizeof(res)); 70 for(int i=0;i<len;i++) 71 { 72 now=next[now][buf[i]-‘ ‘]; 73 int tmp=now; 74 while(tmp!=root) 75 { 76 if(end[tmp]!=-1) 77 { 78 if(!mark[end[tmp]]) 79 { 80 res[++res[0]]=end[tmp]; 81 mark[end[tmp]]=1; 82 } 83 } 84 tmp=fail[tmp]; 85 } 86 } 87 if(res[0]) 88 { 89 printf("web %d: ",id); 90 sort(res+1,res+res[0]+1); 91 for(int i=1;i<=res[0];i++) 92 { 93 printf("%d%c",res[i],i==res[0]?‘\n‘:‘ ‘); 94 } 95 return 1; 96 } 97 return 0; 98 } 99 }; 100 trie ac; 101 char buf[20005]; 102 int main() 103 { 104 int n,m; 105 while(~scanf("%d",&n)) 106 { 107 ac.init(); 108 for(int i=1;i<=n;i++) 109 { 110 scanf("%s",buf); 111 ac.insert(buf,i); 112 } 113 ac.build(); 114 scanf("%d",&m); 115 int total=0; 116 for(int i=1;i<=m;i++) 117 { 118 scanf("%s",buf); 119 total+=ac.query(buf,i); 120 } 121 printf("total: %d\n",total); 122 } 123 return 0; 124 }
真情推荐kuangbin大神的关于ac自动机的博客:http://www.cnblogs.com/kuangbin/category/402395.html
标签:保存 那是 tar display get 世界 心路历程 gif 不同
原文地址:http://www.cnblogs.com/wang-ya-wei/p/6091586.html