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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

P3808,P3796-[模板]AC自动机(简单版/加强版)

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

簡單版

題目鏈接:
https://www.luogu.org/problem/P3808


題目大意

nnn個模式串,一個文本串,求有多少個模式串出現在文本串里。


解題思路

普通ACACAC自動機不解釋。


codecodecode

#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int N=1e6+100; int n,ans; char s[N]; struct ACmac{int fail[N],son[N][30],siz[N],cnt;queue<int> q;void Make(char *s){int x=1,len=strlen(s);for(int i=0;i<len;i++){int c=s[i]-'a';if(!son[x][c]){son[x][c]=++cnt;memset(son[cnt],0,sizeof(son[cnt]));}x=son[x][c];}siz[x]++;return;}void Bfs(){for(int i=0;i<26;i++)son[0][i]=1;q.push(1);fail[1]=0;while(!q.empty()){int x=q.front();q.pop();for(int i=0;i<26;i++){if(!son[x][i]) son[x][i]=son[fail[x]][i];else{q.push(son[x][i]);int y=fail[x];fail[son[x][i]]=son[y][i];}}}}void Find(char *s){int x=1,len=strlen(s);for(int i=0;i<len;i++){int c=s[i]-'a',k=son[x][c];while(k>1&&siz[k]){ans+=siz[k];siz[k]=0;k=fail[k];}x=son[x][c];}return;} }Ac; int main() {scanf("%d",&n);Ac.cnt=1;for(int i=0;i<26;i++)Ac.son[0][i]=1,Ac.son[1][i]=0;for(int i=1;i<=n;i++){scanf("%s",s);Ac.Make(s);}Ac.Bfs();scanf("%s",s);Ac.Find(s);printf("%d\n",ans); }

復雜版

題目鏈接:
https://www.luogu.org/problem/P3796


題目大意

nnn個模式串,一個文本串,求在文本串中出現次數最多的模式串并輸出


解題思路

在末尾結點維護一個當前模式串的編號,然后匹配的時候將答案統計到那個編號里即可。


codecodecode

#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int N=1e6+100; int n; char s[160][90],S[N]; struct ansnode{int w,pos; }ans[N]; struct ACmac{int fail[N],son[N][30],ed[N],cnt;queue<int> q;void Make(char *s,int num){int x=1,len=strlen(s);for(int i=0;i<len;i++){int c=s[i]-'a';if(!son[x][c]){son[x][c]=++cnt;memset(son[cnt],0,sizeof(son[cnt]));}x=son[x][c];}ed[x]=num;return;}void Bfs(){for(int i=0;i<26;i++)son[0][i]=1;q.push(1);fail[1]=0;while(!q.empty()){int x=q.front();q.pop();for(int i=0;i<26;i++){if(!son[x][i]) son[x][i]=son[fail[x]][i];else{q.push(son[x][i]);int y=fail[x];fail[son[x][i]]=son[y][i];}}}}void Find(char *s){int x=1,len=strlen(s);for(int i=0;i<len;i++){int c=s[i]-'a',k=son[x][c];for(;k;k=fail[k])ans[ed[k]].w++;x=son[x][c];}return;} }Ac; bool cMp(ansnode x,ansnode y) {return x.w==y.w?x.pos<y.pos:x.w>y.w;} int main() {while(1){scanf("%d",&n);if(!n) return 0;Ac.cnt=1;memset(Ac.son,0,sizeof(Ac.son));memset(Ac.fail,0,sizeof(Ac.fail));memset(Ac.ed,0,sizeof(Ac.ed));for(int i=0;i<26;i++)Ac.son[0][i]=1,Ac.son[1][i]=0;for(int i=1;i<=n;i++){scanf("%s",s[i]);ans[i].pos=i;ans[i].w=0;Ac.Make(s[i],i);}Ac.Bfs();scanf("%s",S);Ac.Find(S);sort(ans+1,ans+1+n,cMp);printf("%d\n%s\n",ans[1].w,s[ans[1].pos]);for(int i=2;i<=n;i++){if(ans[i].w==ans[i-1].w)printf("%s\n",s[ans[i].pos]);else break;}} }

總結

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

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