题目描述
有N个由小写字母组成的模式串以及一个文本串T。每个模式串可能会在文本串中出现多次。你需要找出哪些模式串在文本串T中出现的次数最多。
输入输出格式
输入格式:输入含多组数据。
每组数据的第一行为一个正整数N,表示共有N个模式串,1≤N≤150。
接下去N行,每行一个长度小于等于707070的模式串。下一行是一个长度小于等于10^6的文本串T。
输入结束标志为N=0。
输出格式:对于每组数据,第一行输出模式串最多出现的次数,接下去若干行每行输出一个出现次数最多的模式串,按输入顺序排列。
输入输出样例
题解
以为加强版会卡时间结果连register都没加就很宽裕的过去了QAQ
然后加强版就只是有一丢丢不一样?都说不上有升级叭QAQ
1 /* 2 qwerta 3 P3796 【模板】AC自动机(加强版) 4 Accepted 5 100 6 代码 C++,2.32KB 7 提交时间 2018-10-07 21:48:13 8 耗时/内存 9 2264ms, 3096KB 10 */ 11 #include<algorithm> 12 #include<iostream> 13 #include<cstring> 14 #include<cstdio> 15 #include<queue> 16 using namespace std; 17 const int lenN=150*70+3; 18 const int lenT=1e6+3; 19 struct emm{ 20 int fail; 21 int nxt[26]; 22 int tag; 23 }AC[lenN];//Tree结构体 24 string s[153]; 25 string st,t; 26 queue<int>q; 27 struct ahh{ 28 int v,nod; 29 }b[153]; 30 bool cmp(ahh qaq,ahh qwq){ 31 if(qaq.v==qwq.v)return qaq.nod<qwq.nod; 32 return qaq.v>qwq.v; 33 } 34 int main() 35 { 36 //freopen("a.in","r",stdin); 37 ios::sync_with_stdio(false); 38 cin.tie(false),cout.tie(false); 39 while(1) 40 { 41 int n; 42 cin>>n; 43 if(n==0)return 0; 44 memset(AC,0,sizeof(AC)); 45 //trie 46 int cnt=0; 47 for(int w=1;w<=n;++w) 48 { 49 cin>>st; 50 int len=st.length(); 51 int now=0; 52 for(int i=0;i<len;++i) 53 { 54 if(!AC[now].nxt[st[i]-'a']) 55 AC[now].nxt[st[i]-'a']=++cnt; 56 now=AC[now].nxt[st[i]-'a']; 57 } 58 AC[now].tag=w;//记录是第几个数组的结尾 59 s[w]=st; 60 } 61 //get_fail 62 { 63 for(int i=0;i<26;++i) 64 if(AC[0].nxt[i]) 65 { 66 AC[AC[0].nxt[i]].fail=0; 67 q.push(AC[0].nxt[i]); 68 } 69 while(!q.empty()) 70 { 71 int x=q.front();q.pop(); 72 for(int i=0;i<26;++i) 73 { 74 if(AC[x].nxt[i]) 75 { 76 AC[AC[x].nxt[i]].fail=AC[AC[x].fail].nxt[i]; 77 q.push(AC[x].nxt[i]); 78 } 79 else 80 AC[x].nxt[i]=AC[AC[x].fail].nxt[i]; 81 } 82 } 83 } 84 //run 85 { 86 memset(b,0,sizeof(b)); 87 for(int i=1;i<=n;++i) 88 b[i].nod=i; 89 cin>>t; 90 int len=t.length(); 91 int now=0; 92 for(int i=0;i<len;++i) 93 { 94 now=AC[now].nxt[t[i]-'a']; 95 for(int u=now;u;u=AC[u].fail) 96 if(AC[u].tag) 97 { 98 b[AC[u].tag].v++; 99 } 100 } 101 //然后是一些奇奇怪怪的句子来输出答案 102 sort(b+1,b+n+1,cmp); 103 cout<<b[1].v<<endl; 104 int k=1; 105 while(b[k].v==b[1].v) 106 { 107 cout<<s[b[k].nod]<<endl; 108 k++; 109 } 110 } 111 } 112 return 0; 113 }