#include <cstdio> #include <cstring> #include <queue> #define Max 1000090 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[26]; T_D *Fail; int Count; int number; T_D () { for (int i = 0; i < 26; i ++) this->child[i] = NULL; Count = 0; Fail = NULL; number = 0; } }; int List[Max << 1]; int List_Cur; bool visit[Max]; class AC_Type { private : T_D *Root; int Trie_Count; public : 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] - ‘a‘; if (now->child[Id] == NULL) { now->child[Id] = new T_D ; now->child[Id]->number = ++ Trie_Count; } now = now->child[Id]; } now->Count ++; } AC_Type () { Trie_Count = 0; Root = new T_D ; Root->number = ++ Trie_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 < 26; 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; } if (pos == NULL) now->child[i]->Fail = Root; } Queue.push (now->child[i]); } } } int Query (char *key) { T_D *now, *pos; int Len = strlen (key); int Id ; now = Root; int res = 0; for (int i = 0; i < Len; i ++) { Id = key[i] - ‘a‘; for (; now->child[Id] && now != Root; now = now->Fail); now = now->child[Id]; if (now == NULL) now = Root; pos = now; for (; pos != Root && !visit[pos->number]; pos = pos->Fail) { res += pos->Count; visit[pos->number] = true; List[++ List_Cur] = pos->number; } for (int i = 1; i <= List_Cur; i ++) visit[List[i]] = false; List_Cur = 0; return res; } return res; } }; AC_Type Make; int N, Q; char line[Max]; char __txt[Max]; int main (int argc, char *argv[]) { read (N); read (Q); scanf ("%s", __txt); for (int i = 1; i <= N; i ++) { scanf ("%s", line); Make.Insert (line); } for (int x, y; Q --; ) { read (x); read (y); y --; -- x; int Cur = 0; for (int i = x; i <= y; i ++) line[++ Cur] = __txt[i]; printf ("%d\n", Make.Query (line)); } return 0; }
时间: 2024-10-11 00:37:13