zoukankan      html  css  js  c++  java
  • 洛谷.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;
    }
    
  • 相关阅读:
    《Python数据挖掘入门与实践》高清中文版PDF+英文版+源码下载
    discuz 论坛配置 QQ/163 网易邮箱
    Discuz! X3 去掉内容图片提示下载方法(去除图片提示下载附件)
    HTTPS的建立过程(SSL建立安全会话的过程)
    前端开发之走进Vue.js
    优雅统计代码耗时的4种方法!
    Maven配置多个远程仓库的实现方法
    idea maven 一直报错“Could not transfer artifact ......(系统找不到指定的路径。)”
    IntelliJ IDEA为类和方法自动添加注释
    maven “mvn clean package”和“mvn clean install”有什么不同?
  • 原文地址:https://www.cnblogs.com/SovietPower/p/8530327.html
Copyright © 2011-2022 走看看