UVALive 4670 Dominating Patterns
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVALive 4670 Dominating Patterns相关的知识,希望对你有一定的参考价值。
题目链接:https://vjudge.net/problem/UVALive-4670
题意:
给一堆字符串和一个文本串,问哪些模式串在文本串中出现的次数最多,输出这个这个次数并输出这些串。
题解:
这道题是白书上的经典(模板水)题,直接上AC自动机的板子,然后xjb搞下,题目中的数据中貌似不存在相同模式串的,所以不用考虑相同串需要输出的次数(拿自己的代码和别人的对拍了一下)。
#include <bits/stdc++.h> using namespace std; const int maxn = 1e6 + 100; const int maxm = 5e5 + 100; struct Aho { struct state { int next[26]; int fail , cnt; }Table[maxm]; int size; map<int,int>mp; map<int,string> mmp; queue<int> que; void init() { mp.clear(),mmp.clear(); while(!que.empty())que.pop(); for(int i = 0 ; i < maxm ; ++i) { memset(Table[i].next , 0 , sizeof(Table[i].next)); Table[i].fail = Table[i].cnt = 0; } size = 1; } void insert(char *S) { int n = strlen(S) , now = 0; for (int i = 0 ; i < n ; ++i) { char c = S[i]; if(!Table[now].next[c - ‘a‘]) Table[now].next[c - ‘a‘] = size++; now = Table[now].next[c - ‘a‘]; } Table[now].cnt++; mmp[now]=S; } void build() { Table[0].fail = -1; que.push(0); while (!que.empty()) { int u = que.front(); que.pop(); for (int i = 0; i < 26; ++i) { if(Table[u].next[i]) { if(u == 0) { Table[Table[u].next[i]].fail = 0; } else { int v = Table[u].fail; while(v != -1) { if(Table[v].next[i]) { Table[Table[u].next[i]].fail = Table[v].next[i]; break; } v = Table[v].fail; } if(v == -1)Table[Table[u].next[i]].fail = 0; } que.push(Table[u].next[i]); } } } } void Get(int u) { while (u) { if(Table[u].cnt)mp[u]++; u = Table[u].fail; } } void match(char *S) { int len = strlen(S), now = 0; for (int i = 0; i < len; ++i) { char c = S[i]; if (Table[now].next[c - ‘a‘]) now = Table[now].next[c - ‘a‘]; else { int p = Table[now].fail; while (p != -1 && !Table[p].next[c - ‘a‘]) p = Table[p].fail; if(p == -1) now = 0; else now = Table[p].next[c - ‘a‘]; } if (Table[now].cnt) Get(now); } } void solve() { if(!mp.size()) { printf("0\n"); for(map<int,string>::iterator x=mmp.begin();x!=mmp.end();++x) { for(int i=0;i<Table[x->first].cnt;++i) { cout << x->second << endl; } } return; } int mx=0; vector<int> g; for(map<int,int>::iterator it=mp.begin();it!=mp.end();++it) { if(it->second > mx) { g.clear(); mx=it->second; g.push_back(it->first); } else if(it->second==mx) g.push_back(it->first); } printf("%d\n",mx); for(auto x:g) { auto it=mmp.find(x); for(int i=0;i<Table[x].cnt;++i) { cout <<it->second<< endl; } } } }aho; int T, N; char S[maxn]; int main() { //freopen("in.txt","r",stdin); while(~scanf("%d" , &N),N) { aho.init(); for(int i = 0; i < N; ++i) { scanf("%s" , S); aho.insert(S); } aho.build(); scanf("%s" , S); aho.match(S); aho.solve(); } return 0; }
以上是关于UVALive 4670 Dominating Patterns的主要内容,如果未能解决你的问题,请参考以下文章
UVALive-4670 Dominating Patterns / 洛谷 3796 模板AC自动机
LA 4670 Dominating Patterns (AC自动机)
LA4670 Dominating Patterns AC自动机模板
LA 4670 Dominating Patterns (AC自动机)