UvaLive 4670 Dominating Patterns
二次联通门 : UvaLive 4670 Dominating Patterns
/* UvaLive 4670 Dominating Patterns AC自动机 题目大意 有个由小写字母组成的模式串以及一个文本串。 每个模式串可能会在文本串中出现多次。 你需要找出哪些模式串在文本串中出现的次数最多。 注意可能会有多组相同的模式串 加个数组判一判就好了。。 具体是在Trie树中的叶节点维护一个small_number 表示最早的串 之后计数什么的, 都记到这个上 */ #include <cstring> #include <cstdio> #include <queue> #define Max 1000009 bool 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 (); } return now > 0; } inline int max (int a, int b) { return a > b ? a : b; } struct Trie_Data { Trie_Data *Fail; Trie_Data *child[26]; int small_number; Trie_Data () { for (int i = 0; i < 26; i ++) this->child[i] = NULL; this->Fail = NULL; small_number = 0; } }; Trie_Data *Root; int number[Max / 1000]; int count[Max / 1000]; char line[Max / 1000][Max / 1000]; char Need[Max]; int Answer; class AC_Type { private : int __Count_; public : void Clear () { __Count_ = 0; memset (number, 0, sizeof (number)); memset (count, 0, sizeof count); } void Insert (char *key) { int Len = strlen (key); __Count_ ++; Trie_Data *now = Root, *pos; int Id; for (int i = 0; i < Len; i ++) { Id = key[i] - 'a'; if (now->child[Id] == NULL) now->child[Id] = new Trie_Data; now = now->child[Id]; } if (!now->small_number) now->small_number = __Count_; number[__Count_] = now->small_number; } void Build_AC () { std :: queue <Trie_Data *> Queue; Queue.push (Root); Trie_Data *now, *pos; while (!Queue.empty ()) { pos = NULL; now = Queue.front (); Queue.pop (); 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]); } } } void Query (char *key) { Trie_Data *now = Root, *pos; int Len = strlen (key); int Id; for (int i = 0; i < Len; i ++) { Id = key[i] - 'a'; for (; now != Root && now->child[Id] == NULL; now = now->Fail); now = now->child[Id]; if (now == NULL) now = Root; for (pos = now; pos != Root; pos = pos->Fail) count[pos->small_number] ++; } } }; AC_Type Make; int main (int argc, char *argv[]) { int N; for (int N; read (N); ) { Root = new Trie_Data; Make.Clear (); for (register int i = 1; i <= N; i ++) { scanf ("%s", line[i]); Make.Insert (line[i]); } Make.Build_AC (); scanf ("%s", Need); Make.Query (Need); Answer = 0; for (int i = 1; i <= N; i ++) Answer = max (Answer, count[i]); printf ("%d\n", Answer); for (int i = 1; i <= N; i ++) if (count[number[i]] == Answer) puts (line[i]); } return 0; }
myj 吊打我Orz,xxy 捆起来打我Orz,myl 文化课上天Orz, lrh 姿势水平敲高Orz, hkd 特别胖Orz%%%,cys 智商感人Orz,syl zz专业Orz,我没有学上, 我们未来一片光明