UVALive-4670 Dominating Patterns(AC自动机)

题目大意:找出出现次数最多的模式串。

题目分析:AC自动机裸题。

代码如下:

# include<iostream>
# include<cstdio>
# include<map>
# include<queue>
# include<cstring>
# include<algorithm>
using namespace std;

const int N=20000;

int ch[N][26];
string p[155];
char s[N*50+5];
int val[N];
int t[155];
int f[N+5];
int last[N+5];
map<string,int>mp;
map<int,string>mpp;

struct AC
{
	int cnt;
	void init()
	{
		cnt=0;
		memset(val,0,sizeof(val));
		memset(ch,0,sizeof(ch));
		memset(t,0,sizeof(t));
	}

	void insert(string str,int v)
	{
		int n=str.size();
		int root=0;
		for(int i=0;i<n;++i){
			int c=str[i]-‘a‘;
			if(!ch[root][c])
				ch[root][c]=++cnt;
			root=ch[root][c];
		}
		val[cnt]=v;
	}

	void getFail()
	{
		queue<int>q;
		f[0]=0;
		for(int i=0;i<26;++i){
			int u=ch[0][i];
			if(!u) continue;
			f[u]=0;
			q.push(u);
			last[u]=0;
		}
		while(!q.empty()){
			int r=q.front();
			q.pop();
			for(int i=0;i<26;++i){
				int u=ch[r][i];
				if(!u) continue;
				q.push(u);
				int v=f[r];
				while(v&&!ch[v][i]) v=f[v];
				f[u]=ch[v][i];
				last[u]=val[f[u]]?f[u]:last[f[u]];
			}
		}
	}

	void ac(char *s)
	{
		int n=strlen(s);
		int j=0;
		for(int i=0;i<n;++i){
			int c=s[i]-‘a‘;
			while(j&&!ch[j][c]) j=f[j];
			j=ch[j][c];
			if(val[j]) getResult(j);
			else if(last[j]) getResult(last[j]);
		}
	}

	void getResult(int u)
	{
		if(u==0) return ;
		if(u) ++t[val[u]];
		getResult(last[u]);
	}
}ac;

int main()
{
	int n;
	while(~scanf("%d",&n)&&n)
	{
		ac.init();
		int cnt=0;
		mp.clear();
		mpp.clear();
		for(int i=0;i<n;++i){
			cin>>p[i];
			if(mp[p[i]]==0) mp[p[i]]=++cnt;
			ac.insert(p[i],cnt);
			mpp[cnt]=p[i];
		}
		scanf("%s",s);

		ac.getFail();
		ac.ac(s);
		int maxn=0;
		for(int i=1;i<=cnt;++i)
			maxn=max(maxn,t[i]);
		cout<<maxn<<endl;
		for(int i=1;i<=cnt;++i)
			if(t[i]==maxn) cout<<mpp[i]<<endl;
	}
	return 0;
}

  

时间: 2024-08-29 17:01:51

UVALive-4670 Dominating Patterns(AC自动机)的相关文章

UVALive 4670 Dominating Patterns --AC自动机第一题

题意:多个模板串,一个文本串,求出那些模板串在文本串中出现次数最多. 解法:AC自动机入门模板题. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <algorithm> #include <string> #include <vector> #in

UVALive - 4670 Dominating Patterns AC 自动机

input n 1<=n<=150 word1 word2 ... wordn 1<=len(wirdi)<=70 s 1<=len(s)<=1000000 output 最多出现次数 出现最多的串,按输入顺序输出,可能出现相同串,也要输出 做法:用一个end数组记下每个串结尾的字符的下标,对应val为1,每次找到就将val++,然后找到最大的val,输出最大val对应的字符串 1 #include <cstdio> 2 #include <queue

LA 4670 Dominating Patterns (AC自动机)

题意:给定一个一篇文章,然后下面有一些单词,问这些单词在这文章中出现过几次. 析:这是一个AC自动机的裸板,最后在匹配完之后再统计数目就好. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <ios

uva 1449 - Dominating Patterns(AC自动机)

题目练级:uva 1449 - Dominating Patterns 题目大意:有一个由小写字母组成的字符串集和一个文本T,要求找出那些字符串在文本中出现的次数最多. 解题思路:将字符串集建立AC自动机,然后传入T进行匹配,对每个匹配上的字符串多应次数加1,最后找出最大值.出现次数与最大值相同的字符串输出.注意字符集中出现相同字符的情况. #include <cstdio> #include <cstring> #include <queue> #include &l

uvalive 4670 Dominating Patterns

在文本串中找出现次数最多的子串. 思路:AC自动机模板+修改一下print函数. 1 #include<stdio.h> 2 #include<math.h> 3 #include<stdio.h> 4 #include<stdlib.h> 5 #include<iostream> 6 #include<string> 7 #include<memory.h> 8 #include<map> 9 #includ

LA4670 Dominating Patterns AC自动机模板

Dominating Patterns 每次看着别人的代码改成自己的模板都很头大...空间少了个0卡了好久 裸题,用比map + string更高效的vector代替蓝书中的处理方法 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <queue> 7

LA 4670 Dominating Patterns (AC自动机)

题意:给定n个字符串和一个文本串,查找哪个字符串出现的次数的最多. 析:一匹配多,很明显是AC自动机.只需要对原来的进行修改一下,就可以得到这个题的答案, 计算过程中,要更新次数,并且要映射字符串.如果用KMP肯定会超时. 代码如下: #include <iostream> #include <cstdio> #include <cstring> #include <map> #include <string> #include <queu

UVALive - 4811 Growing Strings (AC自动机+dp)

题目链接:UVALive - 4811 Growing Strings 题意: 给你n个字符串,问你最多能选出多少个字符串,使得s[i]是s[i+1]的子串. 题解: 先将所有的字符串插入AC自动机,将所有字符串按长度排序后,显然dp[i]=max{dp[j]}+1,其中s[j]是s[i]的子串.然后就完了. 1 #include<bits/stdc++.h> 2 #define mst(a,b) memset(a,b,sizeof(a)) 3 #define F(i,a,b) for(int

AC自动机 LA 4670 Dominating Patterns

题目传送门 题意:训练之南(P216) 分析:求出现最多次数的字串,那么对每个字串映射id,cnt记录次数求最大就可以了. #include <bits/stdc++.h> using namespace std; const int N = 150 + 5; const int NODE = N * 70; const int LEN = 1e6 + 5; const int SIZE = 26; struct AC { int ch[NODE][SIZE], fail[NODE], val

Dominating Patterns (AC 自动鸡模版题, 出现次数最多的子串)

传送门 题意: 给你n个模式串, 再给你一个 文本串,问模式串在文本串中出现次数最多是多少. 出现次数最多的模式串有哪些. 解: 模版题. #include <bits/stdc++.h> #define LL long long #define rep(i, j, k) for(int i = j; i <= k; i++) #define dep(i, j, k) for(int i = k; i >= j; i--) #define mem(i, j) memset(i, j