二次联通门 : HDU 2896 病毒侵袭
/* HDU 2896 病毒侵袭 AC自动机 此题太坑啦。。。 用G++交会无限MLE 行尾不输出回车会无限WA。。 写的程序没错 却交了N遍。。 */ #include <cstring> #include <cstdio> #include <queue> #define Max 100090 void read (int &now) { now = 0; register char word = getchar (); while (word < '0' || word > '9') word = getchar (); while (word >= '0' && word <= '9') { now = now * 10 + word - '0'; word = getchar (); } } struct T_D { T_D *child[133]; T_D *Fail; int number; T_D () { for (int i = 0; i < 133; i ++) this->child[i] = NULL; Fail = NULL; number = 0; } }; bool visit[Max / 50]; T_D *Root; int Number; int Print_Count; int N, M; class AC_Type { private : int __Count_; public : AC_Type () { __Count_ = 0; } void Insert (char *key) { T_D *now = Root, *pos; int Len = strlen (key); int Id; for (int i = 0; i < Len; i ++) { Id = key[i]; if (now->child[Id] == NULL) now->child[Id] = new T_D; now = now->child[Id]; } now->number = ++ __Count_; } void Build_AC () { std :: queue <T_D *> Queue; Queue.push (Root); T_D *now, *pos; while (!Queue.empty ()) { now = Queue.front (); Queue.pop (); pos = NULL; for (int i = 0; i < 133; i ++) { if (now->child[i] == NULL) continue; if (now == Root) now->child[i]->Fail = Root; else { for (pos = now->Fail; pos; pos = pos->Fail) if (pos->child[i]) { now->child[i]->Fail = pos->child[i]; break; } } Queue.push (now->child[i]); } } } void Query (char *key) { T_D *now = Root, *pos; int Len = strlen (key); int Id; bool flag = false; for (int i = 0; i < Len; i ++) { Id = key[i]; for (; now != Root && now->child[Id] == NULL; now = now->Fail); now = now->child[Id]; now = !now ? Root : now; for (pos = now; pos != Root; pos = pos->Fail) { if (pos->number > 0) flag = true; visit[pos->number] = true; } } if (flag) Print (); } void Print () { printf ("web %d:", Number); visit[0] = false; Print_Count ++; for (int i = 1; i <= N; i ++) if (visit[i]) { printf (" %d", i); visit[i] = false; } putchar (' '); } }; AC_Type Make; char line[Max]; int main (int argc, char *argv[]) { Root = new T_D ; read (N); for (int i = 1; i <= N; i ++) { scanf ("%s", line); Make.Insert (line); } Make.Build_AC (); read (M); for (int i = 1; i <= M; i ++) { scanf ("%s", line); Number = i; Make.Query (line); } printf ("total: %d ", Print_Count); return 0; }