完全忘了AC自动机怎么写了qwq,更别说AC自动机上DP了。
今天就好好地学习字符串好了qwq
提一下AC自动机的时间复杂度——设n是模式串的个数,m是文本串的长度,l是模式串的平均长度,那么它的时间复杂度就是\(O(n+m)*l\)。
AC自动机上fail指针指向的点,从root到它代表的是其后缀。
简单版:给定一个文本串,和多个模式串。求有多少个模式串在文本串中出现过。qwqwq
#include
#include
#include
#include
#include
#include
#define MAXN 1000010
using namespace std;
int cnt,n;
char s[MAXN];
struct tree{int fail,end,t[26];}ac[MAXN];
inline void build(char s[])
{
int len=strlen(s);
int now=0;
for(int i=0;iq;
for(int i=0;i<=25;i++)
if(ac[0].t[i]!=0)
ac[ac[0].t[i]].fail=0,q.push(ac[0].t[i]);
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=0;i<=25;i++)
{
if(ac[u].t[i]!=0)
{
ac[ac[u].t[i]].fail=ac[ac[u].fail].t[i];
q.push(ac[u].t[i]);
}
else ac[u].t[i]=ac[ac[u].fail].t[i];
}
}
}
inline int ac_query(char s[])
{
int len=strlen(s);
int now=0,ans=0;
for(int i=0;i
加强版:给定一个文本串和许多模式串,问在文本串中出现次数最多的模式串?以及出现的次数。
#include
#include
#include
#include
#include
#define MAXN 1000010
using namespace std;
int cnt,n;
char s[1000][100],q[MAXN];
struct tree{int fail,end,t[26];}ac[MAXN];
struct Ans{int num,pos;}ans[MAXN];
inline bool cmp(struct Ans x,struct Ans y)
{
if(x.num!=y.num) return x.num>y.num;
else return x.posq;
for(int i=0;i<=25;i++)
{
if(ac[0].t[i]!=0)
ac[ac[0].t[i]].fail=0,q.push(ac[0].t[i]);
}
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=0;i<=25;i++)
{
if(ac[u].t[i]!=0)
{
ac[ac[u].t[i]].fail=ac[ac[u].fail].t[i];
q.push(ac[u].t[i]);
}
else ac[u].t[i]=ac[ac[u].fail].t[i];
}
}
}
inline void ac_query(char s[])
{
int len=strlen(s),now=0;
for(int i=0;i