1. 程式人生 > >UVALive 4670 Dominating Patterns

UVALive 4670 Dominating Patterns

mina %d table ear begin tps c++ href 需要

題目鏈接: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; }
aho

UVALive 4670 Dominating Patterns