日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P3796 【模板】AC自动机(加强版)

發布時間:2024/4/15 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P3796 【模板】AC自动机(加强版) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

P3796 【模板】AC自動機(加強版)

https://www.luogu.org/problemnew/show/P3796

題目描述

NN個由小寫字母組成的模式串以及一個文本串TT。每個模式串可能會在文本串中出現多次。你需要找出哪些模式串在文本串TT中出現的次數最多。

輸入輸出格式

輸入格式:

?

輸入含多組數據。

每組數據的第一行為一個正整數NN,表示共有NN個模式串,1 \leq N \leq 1501N150。

接下去NN行,每行一個長度小于等于7070的模式串。下一行是一個長度小于等于10^6106的文本串TT。

輸入結束標志為N=0N=0。

?

輸出格式:

?

對于每組數據,第一行輸出模式串最多出現的次數,接下去若干行每行輸出一個出現次數最多的模式串,按輸入順序排列。

?

輸入輸出樣例

輸入樣例#1:?
2 aba bab ababababac 6 beta alpha haha delta dede tata dedeltalphahahahototatalpha 0 輸出樣例#1:?
4 aba 2 alpha haha

?

1 #include<bits/stdc++.h> 2 using namespace std; 3 #define lson l,mid,rt<<1 4 #define rson mid+1,r,rt<<1|1 5 #define sqr(x) ((x)*(x)) 6 #define maxn 1000005 7 typedef long long ll; 8 typedef unsigned long long ull; 9 const ull MOD=257; 10 /*#ifndef ONLINE_JUDGE 11 freopen("1.txt","r",stdin); 12 #endif */ 13 14 struct tree{ 15 int fail; 16 int vis[26]; 17 int num; 18 }ac[1000005]; 19 20 int cnt=0; 21 22 struct ANS{ 23 int num,pos; 24 bool operator<(const ANS &b){ 25 if(num==b.num) return pos<b.pos; 26 return num>b.num; 27 } 28 }ans[155]; 29 30 void Clear(int x){ 31 memset(ac[x].vis,0,sizeof(ac[0].vis)); 32 ac[x].num=ac[x].fail=0; 33 } 34 35 void build(string s,int flag){///建trie樹 36 int len=s.length(); 37 int now=0; 38 for(int i=0;i<len;i++){ 39 if(ac[now].vis[s[i]-'a']==0){ 40 ac[now].vis[s[i]-'a']=++cnt; 41 Clear(cnt); 42 } 43 now=ac[now].vis[s[i]-'a']; 44 } 45 ac[now].num=flag; 46 } 47 48 void get_fail(){///構建成trie圖 49 queue<int>Q; 50 ac[0].fail=0; 51 for(int i=0;i<26;i++){ 52 if(ac[0].vis[i]){ 53 ac[ac[0].vis[i]].fail=0; 54 Q.push(ac[0].vis[i]); 55 } 56 } 57 while(!Q.empty()){ 58 int u=Q.front(); 59 Q.pop(); 60 for(int i=0;i<26;i++){ 61 if(ac[u].vis[i]){ 62 ac[ac[u].vis[i]].fail=ac[ac[u].fail].vis[i]; 63 Q.push(ac[u].vis[i]); 64 } 65 else{ 66 ac[u].vis[i]=ac[ac[u].fail].vis[i];///如果當前結點不存在,就指向父親結點的fail指向的結點的子結點 67 } 68 } 69 } 70 } 71 72 void ac_query(string s){ 73 int len=s.length(); 74 int now=0; 75 for(int i=0;i<len;i++){ 76 now=ac[now].vis[s[i]-'a']; 77 for(int t=now;t&&ac[t].num!=-1;t=ac[t].fail){ 78 ans[ac[t].num].num++; 79 } 80 } 81 } 82 83 string s[155]; 84 85 int main(){ 86 #ifndef ONLINE_JUDGE 87 freopen("1.txt","r",stdin); 88 #endif 89 std::ios::sync_with_stdio(false); 90 int n; 91 while(cin>>n){ 92 if(!n) break; 93 Clear(0); 94 for(int i=1;i<=n;i++){ 95 cin>>s[i]; 96 build(s[i],i); 97 ans[i].num=0; 98 ans[i].pos=i; 99 } 100 get_fail(); 101 cin>>s[0]; 102 ac_query(s[0]); 103 sort(ans+1,ans+n+1); 104 cout<<ans[1].num<<endl; 105 cout<<s[ans[1].pos]<<endl; 106 for(int i=2;i<=n;i++){ 107 if(ans[i].num==ans[i-1].num){ 108 cout<<s[ans[i].pos]<<endl; 109 } 110 else{ 111 break; 112 } 113 } 114 } 115 } View Code

?

轉載于:https://www.cnblogs.com/Fighting-sh/p/10363717.html

總結

以上是生活随笔為你收集整理的P3796 【模板】AC自动机(加强版)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。