• AC自动机 板子


    在Trie上做KMP

    https://www.luogu.org/problemnew/show/3808

    #include<cstdio>
    #include<queue>
    #include<iostream>
    #define FOR(i,s,t) for(register int i=s;i<=t;++i)
    using std::cin;
    const int N=4000011;
    char s[N];
    int tot,n,ans;
    namespace AC_automaton{
    	struct Tire{
    		int cnt,fail;
    		int to[27];
    	}tr[N];
    	inline void build_tire(){
    		int u=0;
    		for(register int i=0;s[i]!='';++i){
    			if(!tr[u].to[s[i]-'a'])
    				tr[u].to[s[i]-'a']=++tot;
    			u=tr[u].to[s[i]-'a'];
    		}
    		++tr[u].cnt;
    	}
    	inline void build_automaton(){		
    		int v,u;
    		std::queue<int>q;
    		FOR(i,0,25)
    			if((v=tr[0].to[i]))
    				q.push(v);
    		int now;
    		while(!q.empty()){
    			now=q.front();q.pop();
    			FOR(i,0,25){
    				v=tr[now].to[i];
    				u=tr[now].fail;
    				if(v){
    					tr[v].fail=tr[u].to[i];
    					q.push(v);
    				}
    				else
    					tr[now].to[i]=tr[u].to[i];
    			}
    		}
    	}
    	inline void match(){
    		int now=0,tmp;
    		for(register int i=0;s[i]!='';++i){
    			now=tr[now].to[s[i]-'a'];
    			tmp=now;
    			while(tmp&&tr[tmp].cnt!=-1){
    				ans+=tr[tmp].cnt;
    				tr[tmp].cnt=-1;
    				tmp=tr[tmp].fail;
    			}
    		}
    	}
    }
    using namespace AC_automaton;
    int main(){
    	scanf("%d
    ",&n);
    	while(n--){
    		scanf("%s",s);
    		build_tire();
    	}
    	tr[0].fail=0;
    	build_automaton();	
    	scanf("%s",s);
    	match();
    	printf("%d
    ",ans);
    	return 0;
    }
    

      

    https://www.luogu.org/problemnew/show/3796

    #include<cstdio>
    #include<queue>
    #define FOR(i,s,t) for(register int i=s;i<=t;++i)
    const int N=1000011;
    std::queue<int>q;
    namespace AC_automaton{
    	int ans[155];
    	char s[233][233];
    	char A[N];
    	struct Tire{
    		int fail;
    		int to[26];
    		int pos;
    		inline void init(){
    			fail=pos=0;
    			FOR(i,0,25)to[i]=0;
    		}
    	}tr[N];
    	int tot;
    	inline void insert(char *s,int pos){
    		int u=0,v;
    		for(register int i=0;s[i]!='';++i){
    			if(!tr[u].to[s[i]-'a'])
    				tr[tr[u].to[s[i]-'a']=++tot].init();		
    			u=tr[u].to[s[i]-'a'];
    		}
    		tr[u].pos=pos;
    	}
    	inline void build_fail(){
    		int u,v,now;
    		FOR(i,0,25)
    			if((u=tr[0].to[i])){
    				tr[u].fail=0;
    				q.push(u);
    			}
    		while(!q.empty()){
    			now=q.front();q.pop();
    			FOR(i,0,25){
    				v=tr[now].to[i];
    				u=tr[now].fail;
    				if(v){
    					tr[v].fail=tr[u].to[i];
    					q.push(v);
    				}
    				else
    					tr[now].to[i]=tr[u].to[i];
    			}
    		}
    	}
    	inline void match(char *s){
    		int now=0,tmp;
    		for(register int i=0;s[i]!='';++i){
    			now=tr[now].to[s[i]-'a'];
    			tmp=now;
    			while(tmp){
    				++ans[tr[tmp].pos];
    				tmp=tr[tmp].fail;
    			}
    		}
    	}
    }
    using namespace AC_automaton;
    int n,mx;
    int main(){
    	while(~scanf("%d",&n)&&n){
    		FOR(i,0,n)
    			ans[i]=0;
    		tot=0;
    		tr[0].fail=0;
    		tr[0].init();
    		FOR(i,1,n){
    			scanf("%s",s[i]);
    			insert(s[i],i);
    		}
    		build_fail();
    		scanf("%s",A);
    		match(A);
    		ans[0]=0;
    		mx=1;
    		FOR(i,1,n)
    			if(ans[mx]<ans[i])
    				mx=i;
    		printf("%d
    ",ans[mx]);
    		FOR(i,1,n)
    			if(ans[mx]==ans[i])
    				printf("%s
    ",s[i]);
    	}
    	return 0;
    } 
    

      

  • 相关阅读:
    mysql之四.表介绍
    mysql之三.mysql的工作流程
    mysql之二.mysql中的存储引擎
    mysql之一.初识mysql
    数据及表结构的导出
    迭代器和生成器
    python字符串格式化的几种方式
    关于global 和 nonlocal你需要注意的问题
    请编写一个函数实现将IP地址转换成一个整数
    Python中__repr__和__str__区别
  • 原文地址:https://www.cnblogs.com/Stump/p/8018715.html
Copyright © 2020-2023  润新知