• 【模板】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
    ",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
    ",res);
        	    for(i=1;i<=n;++i) if(num[i]==res) printf("%s
    ",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!

  • 相关阅读:
    Linux打包&压缩 tar,gzip,bzip2
    Linux递归计算目录md5
    fetion飞信登录异常,错误码10033201、10033202
    Linuxscp如何实现nohup &后台启动
    Linux显示日文4字节半角字符
    Linux目录配置的依据FHS
    Linux解决中文乱码问题: vim/pdf/gedit
    ery validator addMethod 方法的使用
    查询今天发帖量 sql
    JAVA反射机制
  • 原文地址:https://www.cnblogs.com/PaperCloud/p/10260901.html
Copyright © 2020-2023  润新知