P3808【模板】AC自动机(简单版)
题意:
本题就是一个最裸的AC自动机模板,问有多少个模式串在文本串中出现,直接套板子即可
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int maxn=500010; queue<int> q; struct AC_Automachine{ int c[maxn][26],val[maxn],fail[maxn],cnt; void ins(char *s){ int len=strlen(s);int now=0; for(int i=0;i<len;i++){ int v=s[i]-'a'; if(!c[now][v]) c[now][v]=++cnt; now=c[now][v]; } val[now]++; } void build(){ for(int i=0;i<26;i++){ if(c[0][i]){ fail[c[0][i]]=0; q.push(c[0][i]); } } while(!q.empty()){ int u=q.front(); q.pop(); for(int i=0;i<26;i++){ if(c[u][i]){ fail[c[u][i]]=c[fail[u]][i]; q.push(c[u][i]); } else c[u][i]=c[fail[u]][i]; } } } int query(char *s){ int len=strlen(s); int now=0,ans=0; for(int i=0;i<len;i++){ now=c[now][s[i]-'a']; for(int t=now;t&&~val[t];t=fail[t]) ans+=val[t],val[t]=-1; } return ans; } }AC; int n; char p[1000005]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%s",p),AC.ins(p); AC.build(); scanf("%s",p); int ans=AC.query(p); cout<<ans<<endl; return 0; }
P3796【模板】AC自动机加强版
题意:
这题是询问哪个模式串出现次数最多,输出出现次数与串,有多个则输出多个,做法也不难,开一个ans[i]数组记录模式串i的出现次数,然后求出最大值,再遍历一遍ans数组,输出与最大值相同的下标对应的字符串。还有一点不同的就是,对于insert操作对每个模式串结尾的标记应该改为模式串的编号才能在ans数组中记录
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<queue> using namespace std; const int maxn=300000; string s[160],temp; int ans[maxn],n; struct AC_Automachine{ int c[maxn][26],val[maxn],fail[maxn],cnt; void init(){ memset(c,0,sizeof(c)); memset(ans,0,sizeof(ans)); memset(val,0,sizeof(val)); memset(fail,0,sizeof(fail)); cnt=0; } void insert(string s,int k){ int now=0; for(int i=0;i<s.length();i++){ int v=s[i]-'a'; if(!c[now][v]) c[now][v]=++cnt; now=c[now][v]; } val[now]=k; } void build(){ queue<int> q; for(int i=0;i<26;i++){ if(c[0][i]){ fail[c[0][i]]=0; q.push(c[0][i]); } } while(!q.empty()){ int u=q.front(); q.pop(); for(int i=0;i<26;i++){ if(c[u][i]){ fail[c[u][i]]=c[fail[u]][i]; q.push(c[u][i]); } else c[u][i]=c[fail[u]][i]; } } } void query(string s){ int now=0; for(int i=0;i<s.length();i++){ now=c[now][s[i]-'a']; for(int t=now;t;t=fail[t]) ans[val[t]]++; } } }AC; int main() { while(scanf("%d",&n)&&n){ AC.init(); for(int i=1;i<=n;i++){ cin>>s[i]; AC.insert(s[i],i); } AC.build(); cin>>temp; AC.query(temp); int pos=0; for(int i=1;i<=n;i++) pos=max(pos,ans[i]); cout<<pos<<endl; for(int i=1;i<=n;i++) if(ans[i]==pos) cout<<s[i]<<endl; } }