生活随笔
收集整理的這篇文章主要介紹了
AC自动机例题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
P3808 [模板]AC自動機(簡單版)
[題目描述]
給定n個模式串和1個文本串,求有多少個模式串在文本串里出現過。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF=1e9+7;
inline LL read(){register LL x=0,f=1;register char c=getchar();while(c<48||c>57){if(c=='-')f=-1;c=getchar();}while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();return f*x;
}const int MAXN=1e6+5;
const int MAXV=26;namespace ACzdj{struct Trie{int v[MAXV];int fail,end;}AC[MAXN];int Ncnt;inline void build(string s){int cur=0,l=s.length();for(int i=0;i<l;i++){if(!AC[cur].v[s[i]-'a'])AC[cur].v[s[i]-'a']=++Ncnt;cur=AC[cur].v[s[i]-'a'];}AC[cur].end+=1;}inline void Get_fail(){queue <int> q;for(int i=0;i<26;i++)if(AC[0].v[i]){AC[AC[0].v[i]].fail=0;q.push(AC[0].v[i]);}while(!q.empty()){int u=q.front();q.pop();for(int i=0;i<26;i++){if(AC[u].v[i]){AC[AC[u].v[i]].fail=AC[AC[u].fail].v[i];q.push(AC[u].v[i]);}elseAC[u].v[i]=AC[AC[u].fail].v[i];}}}inline int query(string s){int res=0;int l=s.length(),cur=0;for(int i=0;i<l;i++){cur=AC[cur].v[s[i]-'a'];for(int t=cur;t&&AC[t].end!=-1;t=AC[t].fail){res+=AC[t].end;AC[t].end=-1;}}return res;}
}using namespace ACzdj;int n;
string s;int main(){n=read();for(int i=1;i<=n;i++){cin>>s;build(s);}AC[0].fail=0;Get_fail();cin>>s;printf("%d\n",query(s));
}
P3796 [模板]AC自動機(加強版)
[題目描述]
有NN個由小寫字母組成的模式串以及一個文本串TT。每個模式串可能會在文本串中出現多次。你需要找出哪些模式串在文本串TT中出現的次數最多。
// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF=1e9+7;
inline LL read(){register LL x=0,f=1;register char c=getchar();while(c<48||c>57){if(c=='-')f=-1;c=getchar();}while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();return f*x;
}const int MAXN=150000;
const int MAXM=155;
const int MAXV=26;struct Node{int num,id;friend bool operator < (Node a,Node b){if(a.num==b.num) return a.id<b.id;return a.num>b.num;}
}ans[MAXM];namespace ACzdj{struct Trie{int v[MAXV];int fail,end;}AC[MAXN];int Ncnt;inline void clear(int x){for (register int i = 0; i < 26; ++i)AC[x].v[i] = 0;AC[x].fail=0,AC[x].end=0;}inline void build(const string& s,int id){int cur=0,l=s.length();for(int i=0;i<l;i++){if(!AC[cur].v[s[i]-'a']){AC[cur].v[s[i]-'a']=++Ncnt;clear(Ncnt);}cur=AC[cur].v[s[i]-'a'];}AC[cur].end=id;}inline void Get_fail(){queue<int> q;for(int i=0;i<26;i++)if(AC[0].v[i]){AC[AC[0].v[i]].fail=0;q.push(AC[0].v[i]);}while(!q.empty()){int u=q.front();q.pop();for(int i=0;i<26;i++){if(AC[u].v[i]){AC[AC[u].v[i]].fail=AC[AC[u].fail].v[i];q.push(AC[u].v[i]);}elseAC[u].v[i]=AC[AC[u].fail].v[i];}}}inline void query(const string& s){int l=s.length(),cur=0;for(int i=0;i<l;i++){cur=AC[cur].v[s[i]-'a'];for(int t=cur;t;t=AC[t].fail)ans[AC[t].end].num++;}}
}using namespace ACzdj;int n;
string s[MAXM];int main(){
// freopen("trie.in","r",stdin);
// freopen("trie.out", "w", stdout);while(n = read()){clear(Ncnt=0);for(int i=1;i<=n;i++){cin>>s[i];ans[i].num=0,ans[i].id=i;build(s[i],i);}AC[0].fail=0;Get_fail();cin>>s[0];query(s[0]);sort(ans+1,ans+n+1);printf("%d\n",ans[1].num);cout<<s[ans[1].id]<<endl;for(int i=2;ans[i].num==ans[i-1].num&&i<=n;i++)//printf("%s\n",s[ans[i].id]);cout<<s[ans[i].id]<<endl;}
}
轉載于:https://www.cnblogs.com/lizehon/p/10390192.html
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生
總結
以上是生活随笔為你收集整理的AC自动机例题的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。