ac自动机基础模板(hdu2222)

In the modern time, Search engine came into the life of everybody like Google, Baidu, etc.
Wiskey also wants to bring this feature to his image retrieval system.

Every image have a long description, when users type some keywords
to find the image, the system will match the keywords with description
of image and show the image which the most keywords be matched.

To simplify the problem, giving you a description of image, and
some keywords, you should tell me how many keywords will be match.

InputFirst line will contain one integer means how many cases will follow by.

Each case will contain two integers N means the number of keywords and N keywords follow. (N <= 10000)

Each keyword will only contains characters ‘a‘-‘z‘, and the length will be not longer than 50.

The last line is the description, and the length will be not longer than 1000000.

OutputPrint how many keywords are contained in the description.Sample Input

1
5
she
he
say
shr
her
yasherhs

Sample Output

3题目就是给定一些串,让你在一个字符串中搜出现几个串。这就是ac自动机的基本模板。注意事项:memset是非常慢的,尽量少用,注意节点的跳转,就是我代码中的u节点,注意scanf printf 而不是cin cout ps:动态开节点,动态初始化,注意是动态。惨痛的经历,刷了一面半的wa tle re加!!为犯错误的地方,引起重视。
#pragma GCC optimize("O2")
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#define maxnode 501000//!!

using namespace std;

struct Trie
{
	int ch[maxnode][26],val[maxnode],fail[maxnode];
	int sz=0,root=0;

	int newnode()//!!
	{
		for(int i=0;i<26;i++)
			ch[sz][i]=-1;
		val[sz++]=0;
		return sz-1;
	}

	void clear(){sz=0;root=newnode();}//!!

	int idx(char s){return s-‘a‘;}

	void insert(char* s)
	{
		int u=0,len=strlen(s);
		for(int i=0;i<len;i++)
		{
			int v=idx(s[i]);
			if(ch[u][v]==-1)
				ch[u][v]=newnode();//!!
			u=ch[u][v];
		}
		val[u]++;
	}

	void build()
	{
		queue<int> q;
		fail[root]=root;
		for(int i=0;i<26;i++)
		{
			if(ch[root][i]==-1)//!!
				ch[root][i]=root;
			else
			{
				fail[ch[root][i]]=root;
				q.push(ch[root][i]);
			}
		}
		while(!q.empty())
		{
			int u=q.front();q.pop();//!!
			for(int i=0;i<26;i++)
			{
				if(ch[u][i]==-1)
					ch[u][i]=ch[fail[u]][i];//!!
				else
				{
					fail[ch[u][i]]=ch[fail[u]][i];//!!
					q.push(ch[u][i]);
				}
			}
		}
	}

	int query(char* s)
	{
		int u=root,len=strlen(s);
		int ans=0;
		for(int i=0;i<len;i++)//!!
		{
			int v=idx(s[i]);
			u=ch[u][v];//!!
			int tmp=u;
			while(tmp!=root)
			{
				ans+=val[tmp];
				val[tmp]=0;//!!
				tmp=fail[tmp];
			}
		}
		return ans;
	}

};
Trie ac;
char  str[maxnode*2];//!!

int main()
{
	int t,n;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		ac.clear();//!!
		while(n--)
		{
			scanf("%s",str);
			ac.insert(str);
		}
		ac.build();
		scanf("%s",str);
		printf("%d\n",ac.query(str));
	}
}
时间: 2024-12-22 10:02:18

ac自动机基础模板(hdu2222)的相关文章

NYOJ 1085 AC自动机基础模板

今天学了AC自动机,可以说AC自动机是把匹配的串建立成为一颗trie,然后就和kmp 是一样的 题意:判断在一篇文章中有多少单词出现过,并输出来 #include<cstdio> #include<cstring> #include<map> #include<queue> #include<iostream> using namespace std; const int maxn = 1000007; int cnt; struct Node{

[hdu2222]ac自动机(模板)

题意:一个文本串+多个模板串的匹配问题 思路:裸的ac自动机. 1 #pragma comment(linker, "/STACK:10240000,10240000") 2 3 #include <iostream> 4 #include <cstdio> 5 #include <algorithm> 6 #include <cstdlib> 7 #include <cstring> 8 #include <map&g

HDU 2222 Keywords Search (AC自动机入门 模板)

AC自动机入门 Aho-Corasick automaton,该算法在1975年产生于贝尔实验室,是著名的多模匹配算法之一.学习AC自动机之前得先有Trie树和KMP模式匹配算法的基础. AC自动机算法分为3步:1.构造一棵tire树  2.构造失败指针  3.进行模式匹配 AC自动机的优化:Trie图 Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other

AC自动机基础

AC自动机不是自动AC机 简介 看dalao们AC自动机的Blog,大多数奆奆都会感性地说: AC_automation = KMP+TRIE 然而在我重蹈覆辙辗转反侧n次后才明白,这东西说了等于没说. AC自动机是一种有限状态自动机(说了等于没说),它常被用于多模式串的字符串匹配. 在学完AC自动机,我也总结出一句说了等于没说的话: AC自动机是以TRIE的结构为基础,结合KMP的思想建立的. 建立AC自动机 建立一个AC自动机通常需要两个步骤: 基础的TRIE结构:将所有的模式串构成一棵Tr

AC自动机【模板】+经典例题

AC自动机模板 经典例题 Keywords Search HDU - 2222 [求目标串中出现了几个模式串] [(注意:模式串可能会重复)] 模板: 1 const int maxn=26; 2 struct Trie 3 { 4 int next[500010][maxn]; 5 int fail[500010],end[500010]; 6 int root,L; 7 int newnode() //初始化 8 { 9 for(int i=0;i<26;i++) 10 next[L][i]

hdoj 2896 病毒侵袭 【AC自动机 基础题】

病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 15893    Accepted Submission(s): 4055 Problem Description 当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻....在这样的时刻,人们却异常兴奋--我们能在有生之年看到500年一遇的世界奇观,那是多么幸福的事

hdoj 3065 病毒侵袭持续中 【AC自动机 基础题】【输出每个模式串出现的次数】

病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 8678    Accepted Submission(s): 3045 Problem Description 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒网站,他有着好多好多

【hdu2222-Keywords Search】AC自动机基础裸题

http://acm.hust.edu.cn/vjudge/problem/16403 题意:给定n个单词,一个字符串,问字符串中出现了多少个单词.(若单词her,he,字符串aher中出现了两个单词) 题解: 每个单词末尾节点sum=1:find的时候每个点都顺着fail往上跳,加上该节点的sum,然后将这个sum清了:注意同一个单词出现多次只算一次. 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring>

HDU-2222 Keywords Search(AC自动机--模板题)

题目大意:统计一共出现了多少次模板串. 题目分析:AC自动机的模板题.不过这题有坑,相同的模板串不能只算一次. 代码如下: # include<iostream> # include<cstdio> # include<queue> # include<map> # include<string> # include<cstring> # include<algorithm> using namespace std; co