病毒侵袭(AC自动机变形)
Problem Description
当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻。。。。在这样的时刻,人们却异常兴奋——我们能在有生之年看到500年一遇的世界奇观,那是多么幸福的事儿啊~~
但网路上总有那么些网站,开始借着民众的好奇心,打着介绍日食的旗号,大肆传播病毒。小t不幸成为受害者之一。小t如此生气,他决定要把世界上所有带病毒的网站都找出来。当然,谁都知道这是不可能的。小t却执意要完成这不能的任务,他说:“子子孙孙无穷匮也!”(愚公后继有人了)。
万事开头难,小t收集了好多病毒的特征码,又收集了一批诡异网站的源码,他想知道这些网站中哪些是有病毒的,又是带了怎样的病毒呢?顺便还想知道他到底收集了多少带病毒的网站。这时候他却不知道何从下手了。所以想请大家帮帮忙。小t又是个急性子哦,所以解决问题越快越好哦~~
但网路上总有那么些网站,开始借着民众的好奇心,打着介绍日食的旗号,大肆传播病毒。小t不幸成为受害者之一。小t如此生气,他决定要把世界上所有带病毒的网站都找出来。当然,谁都知道这是不可能的。小t却执意要完成这不能的任务,他说:“子子孙孙无穷匮也!”(愚公后继有人了)。
万事开头难,小t收集了好多病毒的特征码,又收集了一批诡异网站的源码,他想知道这些网站中哪些是有病毒的,又是带了怎样的病毒呢?顺便还想知道他到底收集了多少带病毒的网站。这时候他却不知道何从下手了。所以想请大家帮帮忙。小t又是个急性子哦,所以解决问题越快越好哦~~
Input
第一行,一个整数N(1<=N<=500),表示病毒特征码的个数。
接下来N行,每行表示一个病毒特征码,特征码字符串长度在20—200之间。
每个病毒都有一个编号,依此为1—N。
不同编号的病毒特征码不会相同。
在这之后一行,有一个整数M(1<=M<=1000),表示网站数。
接下来M行,每行表示一个网站源码,源码字符串长度在7000—10000之间。
每个网站都有一个编号,依此为1—M。
以上字符串中字符都是ASCII码可见字符(不包括回车)。
接下来N行,每行表示一个病毒特征码,特征码字符串长度在20—200之间。
每个病毒都有一个编号,依此为1—N。
不同编号的病毒特征码不会相同。
在这之后一行,有一个整数M(1<=M<=1000),表示网站数。
接下来M行,每行表示一个网站源码,源码字符串长度在7000—10000之间。
每个网站都有一个编号,依此为1—M。
以上字符串中字符都是ASCII码可见字符(不包括回车)。
Output
依次按如下格式输出按网站编号从小到大输出,带病毒的网站编号和包含病毒编号,每行一个含毒网站信息。
web 网站编号: 病毒编号 病毒编号 …
冒号后有一个空格,病毒编号按从小到大排列,两个病毒编号之间用一个空格隔开,如果一个网站包含病毒,病毒数不会超过3个。
最后一行输出统计信息,如下格式
total: 带病毒网站数
冒号后有一个空格。
web 网站编号: 病毒编号 病毒编号 …
冒号后有一个空格,病毒编号按从小到大排列,两个病毒编号之间用一个空格隔开,如果一个网站包含病毒,病毒数不会超过3个。
最后一行输出统计信息,如下格式
total: 带病毒网站数
冒号后有一个空格。
Sample Input
3
aaa
bbb
ccc
2
aaabbbccc
bbaacc
Sample Output
web 1: 1 2 3
total: 1
Source
Recommend
1 #include <stdio.h> 2 #include <iostream> 3 #include <algorithm> 4 #include <string.h> 5 #include <stdlib.h> 6 #include <math.h> 7 #include <queue> 8 #include <set> 9 10 #define INF 0x3f3f3f3f 11 #define pii pair<int,int> 12 using namespace std; 13 14 15 16 17 struct ac_automation{ 18 int next[210*500][128],fail[210*500],end[210*500]; 19 int root,L; 20 bool vis[510]; 21 int newnode(){ 22 for (int i=0;i<128;i++) 23 { 24 next[L][i] = -1; 25 } 26 end[L++] = 0; 27 return L-1; 28 } 29 void init(){ 30 L = 0; 31 root = newnode(); 32 } 33 void insert(char s[],int id){ 34 int len = strlen(s); 35 int now = root; 36 for (int i=0;i<len;i++){ 37 if (next[now][s[i]] == -1) 38 next[now][s[i]] = newnode(); 39 now = next[now][s[i]]; 40 } 41 end[now] = id; 42 } 43 void build(){ 44 queue<int > Q; 45 fail[root] = root; 46 for (int i=0;i<128;i++) 47 { 48 if (next[root][i] == -1) 49 next[root][i] = root; 50 else{ 51 fail[next[root][i]] = root; 52 Q.push(next[root][i]); 53 } 54 } 55 while (!Q.empty()){ 56 int now = Q.front(); 57 Q.pop(); 58 for (int i=0;i<128;i++){ 59 if (next[now][i] == -1) 60 next[now][i] = next[fail[now]][i]; 61 else{ 62 fail[next[now][i]] = next[fail[now]][i]; 63 Q.push(next[now][i]); 64 } 65 } 66 } 67 } 68 bool querry(char buf[],int n,int id){ 69 int len = strlen(buf); 70 int now = root; 71 bool flag = false; 72 memset(vis,false, sizeof(vis)); 73 for (int i=0;i<len;i++){ 74 now = next[now][buf[i]]; 75 int temp = now; 76 while (temp!=root){ 77 if (end[temp]!=0){ 78 vis[end[temp]] = true; 79 flag = true; 80 } 81 temp = fail[temp]; 82 } 83 } 84 if (!flag) 85 return false; 86 printf("web %d:",id); 87 for (int i=1;i<=n;i++) 88 { 89 if (vis[i]) 90 printf(" %d",i); 91 } 92 printf("\n"); 93 return true; 94 } 95 }; 96 ac_automation ac; 97 char buf[10010]; 98 int main(){ 99 int n,m; 100 while (scanf("%d",&n)!=EOF){ 101 ac.init(); 102 for (int i=1;i<=n;i++){ 103 scanf("%s",buf); 104 ac.insert(buf,i); 105 } 106 ac.build(); 107 int ans = 0; 108 scanf("%d",&m); 109 for (int i=1;i<=m;i++){ 110 scanf("%s",buf); 111 if (ac.querry(buf,n,i)) 112 ans++; 113 } 114 printf("total: %d\n",ans); 115 } 116 return 0; 117 }