HDU-2896-AC自动机
http://acm.hdu.edu.cn/showproblem.php?pid=2896
病毒侵袭
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 32352 Accepted Submission(s): 7365
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
AC自动机裸题,因为字符种类多导致ME两次,最后随便改成7w就A了= =
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAX_SIG=95; 4 const int MAX_NOD=70010; 5 int idx(char c){return c-33;} 6 struct node 7 { 8 int next[MAX_SIG]; 9 int cnt,fail,id; 10 }; 11 struct ach 12 { 13 node AC[MAX_NOD]; 14 bool vis[505]; 15 int size,ID; 16 void init() 17 { 18 memset(AC,0,sizeof(AC)); 19 size=ID=1; 20 AC[0].fail=-1; 21 } 22 23 void insert(char *S){ 24 int u=0,n=strlen(S); 25 for(int i=0;i<n;++i){ 26 int c=idx(S[i]); 27 if(!AC[u].next[c]) AC[u].next[c]=size++; 28 u=AC[u].next[c]; 29 } 30 AC[u].cnt++; 31 AC[u].id=ID++; 32 } 33 34 void build_fail() 35 { 36 queue<int>q; 37 q.push(0); 38 while(!q.empty()){ 39 int u=q.front(); 40 q.pop(); 41 for(int i=0;i<MAX_SIG;++i){ 42 if(AC[u].next[i]){ 43 int v=AC[u].fail; 44 while(v!=-1&&AC[v].next[i]==0) v=AC[v].fail; 45 if(v==-1) AC[AC[u].next[i]].fail=0; 46 else{ 47 AC[AC[u].next[i]].fail=AC[v].next[i]; 48 } 49 q.push(AC[u].next[i]); 50 } 51 } 52 } 53 } 54 55 void cal(int u){ 56 while(u!=-1){ 57 if(AC[u].cnt) vis[AC[u].id]=1; 58 u=AC[u].fail; 59 } 60 } 61 62 int solve(char *S,int cas){ 63 memset(vis,0,sizeof(vis)); 64 int u=0,n=strlen(S); 65 for(int i=0;i<n;++i){ 66 int c=idx(S[i]); 67 if(AC[u].next[c])u=AC[u].next[c]; 68 else{ 69 u=AC[u].fail; 70 while(u!=-1&&AC[u].next[c]==0) u=AC[u].fail; 71 if(u==-1) u=0; 72 else u=AC[u].next[c]; 73 } 74 if(AC[u].cnt){ 75 cal(u); 76 } 77 } 78 int ret=0; 79 for(int i=1;i<=500;++i) 80 { 81 if(vis[i]){ 82 if(ret==0){ 83 printf("web %d:",cas); 84 } 85 printf(" %d",i); 86 ret++; 87 } 88 } 89 if(ret)puts(""); 90 return ret==0?0:1; 91 } 92 }a; 93 int main() 94 { 95 int N,M; 96 a.init(); 97 char S[210]; 98 char T[10010]; 99 cin>>N; 100 for(int i=1;i<=N;++i){ 101 scanf("%s",S); 102 a.insert(S); 103 } 104 a.build_fail(); 105 int ans=0; 106 cin>>M; 107 for(int i=1;i<=M;++i){ 108 scanf("%s",T); 109 ans+=a.solve(T,i); 110 } 111 printf("total: %d\n",ans); 112 return 0; 113 }
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<map> 5 #include<set> 6 #include<stack> 7 #include<deque> 8 #include<bitset> 9 #include<unordered_map> 10 #include<unordered_set> 11 #include<queue> 12 #include<cstdlib> 13 #include<ctype.h> 14 #include<ctime> 15 #include<functional> 16 #include<algorithm> 17 #include<bits/stdc++.h> 18 using namespace std; 19 #define LL long long 20 #define pii pair<int,int> 21 #define mp make_pair 22 #define pb push_back 23 #define fi first 24 #define se second 25 #define inf 0x3f3f3f3f 26 #define debug puts("debug") 27 #define mid ((L+R)>>1) 28 #define lc (id<<1) 29 #define rc (id<<1|1) 30 const int maxn=300020; 31 const int maxm=200020; 32 const double PI=acos(-1.0); 33 const double eps=1e-6; 34 const LL mod=1e9+7; 35 LL gcd(LL a,LL b){return b==0?a:gcd(b,a%b);} 36 LL lcm(LL a,LL b){return a/gcd(a,b)*b;} 37 LL qpow(LL a,LL b,LL c){LL r=1; for(;b;b>>=1,a=a*a%c)if(b&1)r=r*a%c;return r;} 38 template<class T> 39 void prt(T v){for(auto x:v)cout<<x<<' ';cout<<endl;} 40 struct Edge{int u,v,w,next;}; 41 42 char T[10010],s[210]; 43 bool vis[550]; 44 int N,M; 45 int ch[60010][100],tot; 46 int f[70010]; 47 int ok[70010]; 48 int newnode(){memset(ch[tot],-1,sizeof(ch[tot]));return tot++;} 49 void insert(char *s,int len,int id){ 50 int u=0; 51 for(int i=0;i<len;++i){ 52 if(ch[u][s[i]-33]==-1)ch[u][s[i]-33]=newnode(); 53 u=ch[u][s[i]-33]; 54 } 55 ok[u]=id; 56 } 57 void build(){ 58 queue<int>q; 59 for(int i=0;i<100;++i){ 60 if(ch[0][i]==-1){ 61 ch[0][i]=0; 62 } 63 else{ 64 f[ch[0][i]]=0; 65 q.push(ch[0][i]); 66 } 67 } 68 while(!q.empty()){ 69 int u=q.front();q.pop(); 70 for(int i=0;i<100;++i){ 71 if(ch[u][i]==-1){ 72 ch[u][i]=ch[f[u]][i]; 73 } 74 else{ 75 f[ch[u][i]]=ch[f[u]][i]; 76 q.push(ch[u][i]); 77 } 78 } 79 } 80 } 81 void gao(int u){ 82 while(u)vis[ok[u]]=1,u=f[u]; 83 } 84 bool solve(char *T,int len,int id){ 85 int u=0,have=0; 86 memset(vis,0,sizeof(vis)); 87 for(int i=0;i<len;++i){ 88 u=ch[u][T[i]-33]; 89 if(ok[u]){ 90 have=1; 91 gao(u); 92 } 93 } 94 if(!have)return 0; 95 printf("web %d:",id); 96 for(int i=1;i<=N;++i){ 97 if(vis[i])printf(" %d",i); 98 }puts(""); 99 return 1; 100 } 101 int main(){ 102 newnode(); 103 scanf("%d",&N); 104 for(int i=0;i<N;++i){ 105 scanf("%s",s); 106 insert(s,strlen(s),i+1); 107 } 108 build(); 109 scanf("%d",&M); 110 int tot=0; 111 for(int i=0;i<M;++i){ 112 scanf("%s",T); 113 tot+=solve(T,strlen(T),i+1); 114 } 115 printf("total: %d\n",tot); 116 return 0; 117 }