标签:line bsp har color from back vector prepare scan
#include <cstring> #include <cstdio> #include <vector> #include <queue> #define Max 100 #define Mod 1000000007LL 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 (); } } int N, M; struct T_D { T_D *child[26]; T_D *Fail; int number; long long value; T_D () { for (int i = 0; i < 26; i ++) this->child[i] = NULL; Fail = NULL; value = 0; number = 0; } }; inline int swap (int &x, int &y) { int now = x; x = y; y = now; } std :: vector <int> List[Max << 1]; T_D *map[Max]; class Tree_Chain_Get_Type { private : int size[Max]; int deep[Max]; int father[Max]; int __to[Max]; int __next[Max]; int Edge_Count; int edge_list[Max]; int top[Max]; int Count; public : inline void Add_Edge (int from, int to) { Edge_Count ++; __to[Edge_Count] = to; __next[Edge_Count] = edge_list[from]; edge_list[from] = Edge_Count; Edge_Count ++; __to[Edge_Count] = from; __next[Edge_Count] = edge_list[to]; edge_list[to] = Edge_Count; } void Dfs_1 (int now, int __father) { int pos = Count ++; deep[now] = deep[__father] + 1; father[now] = __father; for (int i = edge_list[now]; i; i = __next[i]) if (__to[i] != __father) Dfs_1 (__to[i], now); size[now] = Count - pos; } void Dfs_2 (int now, int chain) { int pos = 0; top[now] = chain; for (int i = edge_list[now]; i; i = __next[i]) if (__to[i] != father[now] && size[pos] < size[__to[i]]) pos = __to[i]; if (!pos) return ; Dfs_2 (pos, chain); for (int i = edge_list[now]; i; i = __next[i]) if (__to[i] != father[now] && __to[i] != pos) Dfs_2 (__to[i], __to[i]); } int Get_Lca (int x, int y) { for (; top[x] != top[y]; x = father[top[x]]) if (deep[top[x]] < deep[top[y]]) swap (x, y); return deep[x] < deep[y] ? x : y; } inline void Prepare () { Count = 0; Dfs_1 (1, 0); Count = 0; Dfs_2 (1, 1); Count = 0; } }; Tree_Chain_Get_Type Make; class AC_Type { private : T_D *Root; int Count; public : AC_Type () { Root = new T_D; Count = 0; Root->number = ++ Count; map[Root->number] = Root; } 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 = ++ Count; map[Count] = now->child[Id]; now->child[Id]->value = (now->value * 26LL + Id) % Mod; } List[i].push_back (now->child[Id]->number); now = now->child[Id]; } } 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]); Make.Add_Edge (now->child[i]->number, now->child[i]->Fail->number); } } } }; AC_Type AC; char line[Max]; int main (int argc, char *argv[]) { int x, y; read (N); for (int i = 1; i <= N; i ++) { scanf ("%s", line); AC.Insert (line); } AC.Build_AC (); Make.Prepare (); int x_1, y_1, x_2, y_2; for (read (M); M --; ) { read (x_1); read (y_1); read (x_2); read (y_2); int now = Make.Get_Lca (List[x_1][y_1 - 1], List[x_2][y_2 - 1]); printf ("%lld\n", map[now]->value); } return 0; }
标签:line bsp har color from back vector prepare scan
原文地址:http://www.cnblogs.com/ZlycerQan/p/7029373.html