• 洛谷.3808/3796.[模板]AC自动机


    题目链接:简单版增强版

    简单版:

    #include <cstdio>
    #include <cstring>
    const int N=1e6+5,S=26;
    
    char s[N];
    struct AC_Automaton
    {
    	int cnt,q[N],val[N],fail[N],las[N],son[N][S];
    //	struct Node
    //	{
    //		int val,las,fail,son[S];
    //		Node *son[S];//指针太麻烦了。。
    //		Node() {val=las=0, memset(son,0,sizeof son);}
    //	}pool[N];
    	void Insert(char *s)
    	{
    		int l=strlen(s),u=0;
    		for(int v,i=0; i<l; ++i)
    		{
    			v=s[i]-'a';
    			if(!son[u][v]) son[u][v]=++cnt;
    			u=son[u][v];
    		}
    		++val[u];
    	}
    	void Build()
    	{
    		int h=0,t=0;
    		for(int i=0; i<S; ++i)
    			if(son[0][i]) fail[son[0][i]]=0,q[t++]=son[0][i];
    		while(h<t)
    		{
    			int x=q[h++];
    			for(int v,i=0; i<S; ++i)
    				if(son[x][i])
    					fail[v=son[x][i]]=son[fail[x]][i], q[t++]=v, las[v]=val[fail[v]]?fail[v]:las[fail[v]];
    				else son[x][i]=son[fail[x]][i];
    		}
    	}
    	int Query(char *s)
    	{
    		int l=strlen(s),res=0,u=0;
    		for(int i=0; i<l; ++i)
    		{
    			u=son[u][s[i]-'a'];
    			for(int p=u; p&&~val[p]; p=las[p])
    				res+=val[p], val[p]=-1;
    		}
    		return res;
    	}
    }ac;
    
    int main()
    {
    	int n; scanf("%d",&n);
    	while(n--) scanf("%s",s), ac.Insert(s);
    	ac.Build();
    	scanf("%s",s), printf("%d",ac.Query(s));
    	return 0;
    }
    
    

    增强版:1920ms(1268ms) 我说怎么慢。。数组开太大了

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    const int N=10505,S=26;
    
    int n;
    char s[155][75],p[1000005];
    struct AC_Automaton
    {
    	int cnt,q[N],val[N],fail[N],las[N],son[N][S],tm[155];
    	void Init()
    	{
    		cnt=0, memset(son,0,sizeof son), memset(val,0,sizeof val);
    	}
    	void Insert(char *s,int id)
    	{
    		int l=strlen(s),u=0;
    		for(int v,i=0; i<l; ++i)
    		{
    			v=s[i]-'a';
    			if(!son[u][v]) son[u][v]=++cnt;
    			u=son[u][v];
    		}
    		val[u]=id;
    	}
    	void Build()
    	{
    		int h=0,t=0;
    		for(int i=0; i<S; ++i)
    			if(son[0][i]) fail[son[0][i]]=0,q[t++]=son[0][i];
    		while(h<t)
    		{
    			int x=q[h++];
    			for(int v,i=0; i<S; ++i)
    				if(son[x][i])
    					fail[v=son[x][i]]=son[fail[x]][i], q[t++]=v, las[v]=val[fail[v]]?fail[v]:las[fail[v]];
    				else son[x][i]=son[fail[x]][i];
    		}
    	}
    	void Query(char *p)
    	{
    		memset(tm,0,sizeof tm);
    		int l=strlen(p),u=0,res=0;
    		for(int i=0; i<l; ++i)
    		{
    			u=son[u][p[i]-'a'];
    			for(int p=u; p; p=las[p])
    				++tm[val[p]];
    		}
    		for(int i=1; i<=n; ++i) res=std::max(res,tm[i]);
    		printf("%d
    ",res);
    		for(int i=1; i<=n; ++i)
    			if(tm[i]==res) printf("%s
    ",s[i]);
    	}
    }ac;
    
    int main()
    {
    	while(scanf("%d",&n),n)
    	{
    		ac.Init();
    		for(int i=1; i<=n; ++i) scanf("%s",s[i]), ac.Insert(s[i],i);
    		ac.Build();
    		scanf("%s",p), ac.Query(p);
    	}
    	return 0;
    }
    

    增强版 第二次写(2018.4.5):1700ms(1204ms)

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    #define gc() getchar()
    const int N=152*72,S=26;
    
    int n;
    char s[152][72],p[1000005];
    
    struct AC_Automaton
    {
    	int tot,son[N][27],fail[N],val[N],las[N],q[N],tm[152];
    	void Init(){
    		tot=0, memset(son,0,sizeof son), memset(val,0,sizeof val);
    	}
    	void Insert(char *s,int pos)
    	{
    		int l=strlen(s),x=0;
    		for(int id,i=0; i<l; ++i)
    		{
    			id=s[i]-'a';
    			if(!son[x][id]) son[x][id]=++tot;
    			x=son[x][id];
    		}
    		val[x]=pos;
    	}
    	void Build()
    	{
    		int h=0,t=0;
    		for(int i=0; i<S; ++i)
    			if(son[0][i]) fail[son[0][i]]=0,q[t++]=son[0][i];
    		while(h<t)
    		{
    			int x=q[h++];
    			for(int v,i=0; i<S; ++i)
    				if(son[x][i])
    					fail[v=son[x][i]]=son[fail[x]][i],q[t++]=v,las[v]=val[fail[v]]?fail[v]:las[fail[v]];
    				else son[x][i]=son[fail[x]][i];
    		}
    	}
    	void Query(char *p)
    	{
    		int l=strlen(p),res=0,x=0;
    		memset(tm,0,sizeof tm);
    		for(int i=0; i<l; ++i)
    		{
    			x=son[x][p[i]-'a'];
    			for(int j=x; j; j=las[j]) ++tm[val[j]];
    		}
    		for(int i=1; i<=n; ++i) if(res<tm[i]) res=tm[i];
    		printf("%d
    ",res);
    		for(int i=1; i<=n; ++i) if(tm[i]==res) printf("%s
    ",s[i]);
    	}
    }ac;
    
    int main()
    {
    	while(scanf("%d",&n),n){
    		ac.Init();
    		for(int i=1; i<=n; ++i) scanf("%s",s[i]),ac.Insert(s[i],i);
    		ac.Build(), scanf("%s",p), ac.Query(p);
    	}
    	return 0;
    }
    
  • 相关阅读:
    ubuntu关闭THP
    ubuntu14安装ambari2.2
    ubuntu14安装ambari2.2
    hcatalog配置
    hcatalog配置
    java.lang.ClassNotFoundException: org.apache.struts2.dispatchet.ng.filter.StrutsPrepareAndExecuteFilter出现这个错误的解决方法
    redis连接的工具类
    案例:服务调用次数控制
    制作redis版的helloworld程序
    redis数据库通用指令
  • 原文地址:https://www.cnblogs.com/SovietPower/p/8530327.html
Copyright © 2020-2023  润新知