【模板】AC自动机

luogu_P3808 【模板】AC自动机(简单版)


Code 

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
	return x*f;
}
const int N=500005;
class AC_automaton{
    private:
		int tr[N][26],cnt,e[N],fail[N];
	public:
    	void insert(char *s)
		{
        	int p=0;
        	for(int i=0;s[i];i++)
			{
        	    int k=s[i]-'a';
        	    if(!tr[p][k])tr[p][k]=++cnt;
        	    p=tr[p][k];
        	}
        	e[p]++;
    	}
    	void build()
		{
    		queue<int>q;
        	memset(fail,0,sizeof(fail));
        	for(int i=0;i<26;i++)if(tr[0][i])q.push(tr[0][i]);
        	while(!q.empty())
			{
        	    int k=q.front();q.pop();
        	    for(int i=0;i<26;i++)
        	        if(tr[k][i])
        	            fail[tr[k][i]]=tr[fail[k]][i],q.push(tr[k][i]);
                	else tr[k][i]=tr[fail[k]][i];
        	}
    	}
    	int query(char *t)
		{
    	    int p=0,res=0;
    	    for(int i=0;t[i];i++)
			{
    	        p=tr[p][t[i]-'a'];
    	        for(int j=p;j&&~e[j];j=fail[j])res+=e[j],e[j]=-1;
    	    }
    	    return res;
    	}
}ac;
int main()
{
	register int n,i;
	register char s[1000005];
	n=read();
	for(i=1;i<=n;++i) scanf("%s",s+1),ac.insert(s+1);ac.build();
	scanf("%s",s+1);return 0*printf("%d\n",ac.query(s+1));
} 

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


Code 

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
	return x*f;
}
#define M(a) memset(a,0,sizeof a)
const int N=70*150;
char s[155][75],t[1000005];
class AC_automaton{
    private:
		int tr[N][26],cnt,e[N],fail[N],num[155];
	public:
		void init(){M(tr);M(e);M(fail);M(num);cnt=0;}
    	void insert(char *s,int t)
		{
        	int p=0;
        	for(int i=0;s[i];i++)
			{
        	    int k=s[i]-'a';
        	    if(!tr[p][k])tr[p][k]=++cnt;
        	    p=tr[p][k];
        	}
        	e[p]=t;
    	}
    	void build()
		{
    		queue<int>q;
        	memset(fail,0,sizeof(fail));
        	for(int i=0;i<26;i++)if(tr[0][i])q.push(tr[0][i]);
        	while(!q.empty())
			{
        	    int k=q.front();q.pop();
        	    for(int i=0;i<26;i++)
        	        if(tr[k][i])
        	            fail[tr[k][i]]=tr[fail[k]][i],q.push(tr[k][i]);
                	else tr[k][i]=tr[fail[k]][i];
        	}
    	}
    	void query(char *t,int n)
		{
    	    int i,p=0,res=0;
    	    for(i=0;t[i];i++)
			{
    	        p=tr[p][t[i]-'a'];
    	        for(int j=p;j;j=fail[j]) num[e[j]]++;
    	    }
    	    for(i=1;i<=n;++i) res=max(res,num[i]);
    	    printf("%d\n",res);
    	    for(i=1;i<=n;++i) if(num[i]==res) printf("%s\n",s[i]+1);
    	}
}ac;
int main()
{
	register int n,i;	
	while(true)
	{
		n=read();
		if(n==0) exit(0);
		ac.init();
		for(i=1;i<=n;++i) scanf("%s",s[i]+1),ac.insert(s[i]+1,i);
		ac.build();
		scanf("%s",t+1);
		ac.query(t+1,n);
	}
	return 0;
} 


Blog来自PaperCloud,未经允许,请勿转载,TKS!

posted @ 2019-01-12 20:18  PaperCloud  阅读(185)  评论(0编辑  收藏  举报