• 模板—字符串—AC自动机(多模式串,单文本串)


    模板—字符串—AC自动机(多模式串,单文本串)

    Code:

    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define N 1000010
    int ch[N][26],fl[N],head[N],to[N],nxt[N],size[N],pos[N],en[N],n,ans; char str[N];
    namespace AC
    {
    	int idx,cnt;
    	void add(int a,int b) {nxt[++idx]=head[a],to[idx]=b,head[a]=idx;}
    	void insert(int id,int len)
    	{
    		int p=0;
    		for(int i=1;i<=len;i++)
    		{
    			if(!ch[p][str[i]-'a'])
    				ch[p][str[i]-'a']=++cnt;
    			p=ch[p][str[i]-'a'];
    		} pos[id]=p,en[p]++;
    	}
    	void dfs(int p)
    	{
    		size[p]=1;
    		for(int i=head[p];i;i=nxt[i])
    			dfs(to[i]),size[p]+=size[to[i]];
    	}
    	void bfs()
    	{
    		idx=0; queue <int> q;
    		for(int i=0;i<26;i++) if(ch[0][i])
    			q.push(ch[0][i]),add(0,ch[0][i]);
    		while(!q.empty())
    		{
    			int p=q.front(); q.pop();
    			for(int i=0;i<26;i++)
    			{
    				int &v=ch[p][i];
    				if(!v) {v=ch[fl[p]][i];continue;}
    				fl[v]=ch[fl[p]][i],q.push(v),add(fl[v],v);
    			}
    		} dfs(0);
    	}
    	void find(int l)
    	{
    		int p=0;
    		for(int i=1;i<=l;i++)
    		{
    			p=ch[p][str[i]-'a']; if(!p) return;
    			for(int j=p;j&&en[j]!=-1;j=fl[j])
    				ans+=en[j],en[j]=-1;
    		}
    	}
    }
    using namespace AC;
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++) scanf("%s",str+1),insert(i,strlen(str+1)); bfs();
    	scanf("%s",str+1),find(strlen(str+1)),printf("%d
    ",ans);
    }
    

      

  • 相关阅读:
    C/C++ 子集生成算法整理
    C++ 求枚举排列的两种方法
    uva1600 Patrol Robot(不同的BFS最短路)
    C++ 已知二叉树两种遍历序列,构建二叉树
    优先队列 C++
    离散化方法
    基本模运算
    C++ 快速幂运算
    病毒通过445端口
    最新勒索软件WannaCrypt病毒感染前后应对措施
  • 原文地址:https://www.cnblogs.com/yangsongyi/p/10655913.html
Copyright © 2020-2023  润新知