1. 程式人生 > >ac自動機基礎模板(hdu2222)

ac自動機基礎模板(hdu2222)

val gin 代碼 strlen ont logs memset define mode

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));
	}
}

ac自動機基礎模板(hdu2222)