hdu 2896 病毒侵袭 AC自动机——多串匹配
http://acm.hdu.edu.cn/showproblem.php?pid=2896
题意:中文......
思路:
这里就知识循环枚举每一个网址即可,set记录每个网址包含的病毒的编号。
//#pragma comment(linker,"/STACK:327680000,327680000") #include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define ll long long #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("din.txt", "r", stdin) #define Write() freopen("dout.txt", "w", stdout); #define M 57 #define N 1000007 using namespace std; struct node { int cnt; node *fail; node *next[95]; void newnode() { cnt = 0; fail = NULL; for (int i = 0; i < 95; ++i) { next[i] = NULL; } } }; set<int>iSet[1007]; struct AC_Automat { public: node *q[N],*root,H[N]; int fr,tl; int t; void init() { fr = tl = 0; t = 0; H[t].newnode(); root = &H[t++]; for (int i = 0; i <= 1000; ++i) iSet[i].clear(); } void insert(char *s,int no) { int i,k; int len = strlen(s); node *p = root; for (i = 0; i < len; ++i) { k = s[i] - 32; if (p->next[k] == NULL) { H[t].newnode(); p->next[k] = &H[t++]; } p = p->next[k]; } p->cnt = no; } void build() { int i; root->fail = NULL; q[tl] = root; node *p; while (fr <= tl) { node *tmp = q[fr++]; for (i = 0; i < 95; ++i) { if (tmp->next[i]) { if (tmp == root) tmp->next[i]->fail = root; else { p = tmp->fail; while (p != NULL) { if (p->next[i]) { tmp->next[i]->fail = p->next[i]; break; } p = p->fail; } if (p == NULL) tmp->next[i]->fail = root; } q[++tl] = tmp->next[i]; } } } } void query(char *s,int no) { int i,k; int len = strlen(s); node *p = root; for (i = 0; i < len; ++i) { k = s[i] - 32; while (p->next[k] == NULL && p != root) p = p->fail; p = p->next[k]; if (p == NULL) p = root; node *tmp = p; while (tmp != root) { if (tmp->cnt != 0) { iSet[no].insert(tmp->cnt); } tmp = tmp->fail; } } } }ac; int n,m; char s1[202],s2[10007]; int main() { int i; while (~scanf("%d",&n)) { ac.init(); for (i = 1; i <= n; ++i) { scanf("%s",s1); ac.insert(s1,i); } ac.build(); scanf("%d",&m); for (i = 1; i <= m; ++i) { scanf("%s",s2); ac.query(s2,i); } int tol = 0; set<int>::iterator it; for (i = 1; i <= m; ++i) { if (iSet[i].size() >= 1) { printf("web %d:",i); tol++; for (it = iSet[i].begin(); it != iSet[i].end(); ++it) { printf(" %d",*it); } printf("\n"); } } printf("total: %d\n",tol); } return 0; }