zoukankan      html  css  js  c++  java
  • 【洛谷P3796】【模板】AC自动机(加强版)

    题目

    题目链接:https://www.luogu.com.cn/problem/P3796
    \(N\) 个由小写字母组成的模式串以及一个文本串 \(T\)。每个模式串可能会在文本串中出现多次。你需要找出哪些模式串在文本串 \(T\) 中出现的次数最多。

    思路

    直接建立 AC 自动机,询问时暴力跳 fail 并记录每个串被走到的次数即可。
    注意为了求出每个串出现次数就不用标记每个点是否被走过了。
    时间复杂度 \(O(|S|\times |T|)\)

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=1000010,M=80,K=160;
    int n,ans,cnt[K];
    char ch[K][M],s[N];
    
    struct ACA
    {
    	int tot,c[M*K][27],fail[M*K],pos[M*K];
    	
    	void clr()
    	{
    		memset(c,0,sizeof(c));
    		memset(fail,0,sizeof(fail));
    		memset(pos,0,sizeof(pos));
    		tot=0;
    	}
    	
    	void ins(char *s,int k)
    	{
    		int len=strlen(s+1),p=0;
    		for (int i=1;i<=len;i++)
    		{
    			int id=s[i]-'a'+1;
    			if (!c[p][id]) c[p][id]=++tot;
    			p=c[p][id];
    		}
    		pos[p]=k;
    	}
    	
    	void build()
    	{
    		queue<int> q;
    		for (int i=1;i<=26;i++)
    			if (c[0][i]) q.push(c[0][i]);
    		while (q.size())
    		{
    			int u=q.front();
    			q.pop();
    			for (int i=1;i<=26;i++)
    				if (c[u][i]) fail[c[u][i]]=c[fail[u]][i],q.push(c[u][i]);
    					else c[u][i]=c[fail[u]][i];
    		}
    	}
    	
    	void query(char *s)
    	{
    		int len=strlen(s+1),p=0;
    		for (int i=1;i<=len;i++)
    		{
    			int id=s[i]-'a'+1;
    			p=c[p][id];
    			for (int j=p;j;j=fail[j])
    				cnt[pos[j]]++;
    		}
    	}
    }AC;
    
    int main()
    {
    	//freopen("data.txt","r",stdin);
    	while (scanf("%d",&n))
    	{
    		if (!n) return 0;
    		memset(cnt,0,sizeof(cnt));
    		AC.clr();
    		for (int i=1;i<=n;i++)
    		{
    			scanf("%s",ch[i]+1);
    			AC.ins(ch[i],i);
    		}
    		scanf("%s",s+1);
    		AC.build();	AC.query(s);
    		ans=0;
    		for (int i=1;i<=n;i++)
    			if (cnt[i]>ans) ans=cnt[i];
    		printf("%d\n",ans);
    		for (int i=1;i<=n;i++)
    			if (cnt[i]==ans) printf("%s\n",ch[i]+1);
    	}
    }
    
  • 相关阅读:
    View Documentation in Web Using [openoffice.org 3+swftools+flexpaper]
    swfobject.js
    Java 文件上传组件 Apache Commons FileUpload 应用指南
    模拟HTML表单上传文件(RFC 1867)
    Using CURL to download a remote file from a valid URL in c++
    GUN tar for windows Practice
    Using libcurl in VC++
    Zlib Practice
    解决HtmlAgilityPack中文乱码
    Windows 7,Windows Server 2008 MSDTC配置
  • 原文地址:https://www.cnblogs.com/stoorz/p/13608958.html
Copyright © 2011-2022 走看看