zoukankan      html  css  js  c++  java
  • luogu3808 luogu3796 AC自动机(简单版) AC自动机(加强版)

    纪念一下我一晚上写了八遍AC自动机

    这是加强版的:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    using namespace std;
    int n, cnt[155], mp[155], len, maxn;
    char a[155][75], b[1000005];
    queue<int> d;
    struct ACzdj{
    	int s[10505][26], val[10505], lst[10505], fai[10505], u, v, siz;
    	//lst[i]是节点i沿失配指针走时遇到的第一个单词节点编号
    	void clr(){
    		siz = maxn = 0;
    		memset(s, 0, sizeof(s));
    		memset(cnt, 0, sizeof(cnt));
    		memset(val, 0, sizeof(val));
    		memset(lst, 0, sizeof(lst));
    		memset(fai, 0, sizeof(fai));
    	}
    	void ins(int k){
    		u = 0;
    		len = strlen(a[k]);
    		for(int i=0; i<len; i++){
    			v = a[k][i] - 'a';
    			if(!s[u][v])	s[u][v] = ++siz;
    			u = s[u][v];
    		}
    		if(!val[u])	val[u] = k;
    		mp[k] = val[u];
    	}
    	void getFail(){
    		for(int i=0; i<26; i++)
    			if(s[0][i])
    				d.push(s[0][i]);
    		while(!d.empty()){
    			u = d.front();
    			d.pop();
    			for(int i=0; i<26; i++){
    				v = s[u][i];
    				if(v){
    					fai[v] = s[fai[u]][i];
    					lst[v] = val[fai[v]]?fai[v]:lst[fai[v]];
    					d.push(v);
    				}
    				else	s[u][i] = s[fai[u]][i];
    			}
    		}
    	}
    	void query(){
    		u = 0;
    		len = strlen(b);
    		for(int i=0; i<len; i++){
    			u = s[u][b[i]-'a'];
    			if(val[u])	cnt[val[u]]++;
    			v = lst[u];
    			while(v){
    				cnt[val[v]]++;
    				v = lst[v];
    			}
    		}
    		for(int i=1; i<=n; i++)
    			maxn = max(maxn, cnt[i]);
    		printf("%d
    ", maxn);
    		for(int i=1; i<=n; i++)
    			if(cnt[mp[i]]==maxn)
    				printf("%s
    ", a[i]);
    	}
    }ac;
    int main(){
    	while(scanf("%d", &n)!=EOF){
    		if(!n)	break;
    		ac.clr();
    		for(int i=1; i<=n; i++){
    			scanf("%s", a[i]);
    			ac.ins(i);
    		}
    		ac.getFail();
    		scanf("%s", b);
    		ac.query();
    	}
    	return 0;
    }
    

    这是简单版的:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    using namespace std;
    char a[1000005];
    queue<int> d;
    int n;
    struct ACzdj{
    	int s[1000005][26], siz, u, v, len, val[1000005], mp[1000005], fai[1000005];
    	int cnt[1000005], lst[1000005];
    	void ins(int k){
    		u = 0;
    		len = strlen(a);
    		for(int i=0; i<len; i++){
    			v = a[i] - 'a';
    			if(!s[u][v])	s[u][v] = ++siz;
    			u = s[u][v];
    		}
    		if(!val[u])	val[u] = k;
    		mp[k] = val[u];
    	}
    	void getFail(){
    		u = 0;
    		for(int i=0; i<26; i++)
    			if(s[0][i])
    				d.push(s[0][i]);
    		while(!d.empty()){
    			u = d.front();
    			d.pop();
    			for(int i=0; i<26; i++){
    				v = s[u][i];
    				if(v){
    					fai[v] = s[fai[u]][i];
    					lst[v] = val[fai[v]]?fai[v]:lst[fai[v]];
    					d.push(v);
    				}
    				else	s[u][i] = s[fai[u]][i];
    			}
    		}
    	}
    	void query(){
    		u = 0;
    		len = strlen(a);
    		for(int i=0; i<len; i++){
    			u = s[u][a[i]-'a'];
    			if(val[u])	cnt[val[u]]++;
    			v = lst[u];
    			while(v){
    				cnt[val[v]]++;
    				v = lst[v];
    			}
    		}
    		int ans=0;
    		for(int i=1; i<=n; i++)
    			if(cnt[mp[i]])
    				ans++;
    		cout<<ans<<endl;
    	}
    }ac;
    int main(){
    	cin>>n;
    	for(int i=1; i<=n; i++){
    		scanf("%s", a);
    		ac.ins(i);
    	}
    	ac.getFail();
    	scanf("%s", a);
    	ac.query();
    	return 0;
    }
    
  • 相关阅读:
    Codeforces 787D. Legacy 线段树优化建图+最短路
    Codeforces 1051E. Vasya and Big Integers
    BZOJ3261 最大异或和
    BZOJ3531 SDOI2014 旅行
    洛谷P2468 SDOI 2010 粟粟的书架
    2018 ICPC 焦作网络赛 E.Jiu Yuan Wants to Eat
    HDU6280 From Tree to Graph
    HDU5985 Lucky Coins 概率dp
    (HDU)1334 -- Perfect Cubes (完美立方)
    (HDU)1330 -- Deck (覆盖物)
  • 原文地址:https://www.cnblogs.com/poorpool/p/7989555.html
Copyright © 2011-2022 走看看