• HDU2222 Keywords Search AC自动机


    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解


    题目传送门 - HDU2222


    题意概括

       先给出一些模式串,然后给出一个母串,统计先前给出的模式串中,有多少个在母串中出现。多组数据。


    题解

      AC自动机模板题。

      首先根据输入数据构建AC自动机。

      然后对于每一位,沿着fail指针走,全部统计并累加。

      有一个小小的优化,就是走过的都标记为-1,下次碰到-1就不走了。因为如果这个节点的标记为-1,那么它的fail一再在它之前就标记成-1了(即统计过了)。


    代码

    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cstdlib>
    #include <cmath>
    using namespace std;
    const int N=10005,L1=55,L2=1000005;
    int T,n,cnt;
    char ch[L1],str[L2];
    struct Trie{
    	int e,fail,Next[26];
    	void init(){
    		e=fail=0;
    		memset(Next,0,sizeof Next);
    	}
    }tree[N*L1];
    void AC_init(){
    	cnt=1;
    	tree[0].init();
    	tree[1].init();
    	for (int i=0;i<26;i++)
    		tree[0].Next[i]=1;
    }
    void build(char ch[]){
    	int rt=1,t,len=strlen(ch);
    	for (int i=0;i<len;i++){
    		t=ch[i]-'a';
    		if (!tree[rt].Next[t]){
    			tree[++cnt].init();
    			tree[rt].Next[t]=cnt;
    		}
    		rt=tree[rt].Next[t];
    	}
    	tree[rt].e++;
    }
    int q[N*L1],head,tail;
    void build_AC(){
    	int rt,k,son;
    	head=tail=0;
    	tree[0].fail=1,tree[1].fail=0;
    	q[++tail]=1;
    	while (head<tail){
    		rt=q[++head];
    		for (int i=0;i<26;i++){
    			son=tree[rt].Next[i];
    			if (!son){
    				tree[rt].Next[i]=tree[tree[rt].fail].Next[i];
    				continue;
    			}
    			k=tree[rt].fail;
    			while (!tree[k].Next[i])
    				k=tree[k].fail;
    			tree[son].fail=tree[k].Next[i];
    			q[++tail]=son;
    		}
    	}
    }
    int solve(){
    	int rt=1,t,len=strlen(str);
    	int ans=0;
    	for (int i=0;i<len;i++){
    		t=str[i]-'a';
    		rt=tree[rt].Next[t];
    		int k=rt;
    		while (~tree[k].e){
    			ans+=tree[k].e;
    			tree[k].e=-1;
    			k=tree[k].fail;
    		}
    	}
    	return ans;
    }
    int main(){
    	scanf("%d",&T);
    	while (T--){
    		scanf("%d",&n);
    		AC_init();
    		for (int i=0;i<n;i++){
    			scanf("%s",ch);
    			build(ch);
    		}
    		build_AC();
    		scanf("%s",str);
    		printf("%d
    ",solve());
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    set-find
    set-equal_range
    set-equal_range
    set-erase
    php 抽象类 静态 单体设计模式
    Servlet 工作原理解析
    职场上一个人情商高的十种表现
    快速学习一门新技术入门
    php中14中排序方式的实现
    php中对Mysql数据库的访问操作
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/HDU2222.html
Copyright © 2020-2023  润新知