hdu 2896 AC自动机

//	hdu 2896 AC自动机
//
//	题目大意:
//
//		给你n个短串,然后给你q串长字符串,要求每个长字符串中
//	是否出现短串,出现的短串各是什么
//
//	解题思路:
//
//		AC自动机,插入单词,构建自动机,然后查询就可以了。
//
//	感悟:
//
//		哎,自己AC自动机果然刚学,还只会个模板,自动机构没构建
//	都不知道。。。继续加油吧~~~FIGHTING!

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

const int MAX_NODE = 200000;

const int SIGMA_SIZE = 131;

struct Aho_Corasick{

	int ch[MAX_NODE][SIGMA_SIZE];
	int val[MAX_NODE];
	int cnt[508];
	int sz;
	int last[MAX_NODE];
	int f[MAX_NODE];

	void clear(){
		memset(cnt,0,sizeof(cnt));
	}

	void init(){
		sz = 1;
		memset(ch[0],0,sizeof(ch[0]));
		val[0] = 0;
	}

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

	void insert(char *s,int v){
		int u = 0;
		int n = strlen(s);
		for (int i=0;i<n;i++){
			//int c = idx(s[i]);
			int c = s[i];
			if (!ch[u][c]){
				memset(ch[sz],0,sizeof(ch[sz]));
				val[sz] = 0;
				ch[u][c] = sz++;
			}
			u = ch[u][c];
		}
		val[u] = v;
	}

	void getfail(){
		queue<int> que;
		for (int c = 0; c < SIGMA_SIZE ; c++){
			int u = ch[0][c];
			if (u){
				que.push(u);
				last[u] = 0;
				f[u] = 0;
			}
		}
		while(!que.empty()){
			int r = que.front();
			que.pop();
			for (int c = 0; c < SIGMA_SIZE ; c++){
				int u = ch[r][c];
				if (!u)
					continue;
				que.push(u);
				int v = f[r];
				while( v && !ch[v][c])
					v = f[v];

				f[u] = ch[v][c];

				last[u] = val[f[u]] ? f[u] : last[f[u]];

			}
		}
	}

	void get_cnt(int u){
		if (u){
			cnt[val[u]]++;
			get_cnt(last[u]);
		}
	}

	void query(char *s){
		int u = 0;
		int n = strlen(s);
		for (int i=0;i<n;i++){
			//char c = idx(s[i]);
			char c = s[i];
			while( u && !ch[u][c])
				u = f[u];

			u = ch[u][c];

			if (val[u]){
				get_cnt(u);
			}
			else if (last[u]){
				get_cnt(last[u]);
			}
		}
	}

}ac;

char str[10009];

int n;

void print(int x,int &num){
	int flag = 0;
	for (int i=1;i<=n;i++){
		if (ac.cnt[i]){
			flag = 1;
			break;
		}
	}
	if (!flag)
		return;

	printf("web %d:",x);

	for (int i=1;i<=n;i++){
		if (ac.cnt[i]){
			printf(" %d",i);
		}
	}
	puts("");
	num++;

}

void input(){
	ac.init();
	for (int i=1;i<=n;i++){
		scanf("%s",str);
		ac.insert(str,i);
	}
	int q;
	int num = 0;
	ac.getfail();
	scanf("%d",&q);
	int x = 1;
	for (int i=1;i<=q;i++){
		scanf("%s",str);
		ac.clear();
		ac.query(str);
		print(i,num);
	}
	printf("total: %d\n",num);
}

int main(){
	//freopen("1.txt","r",stdin);
	while(scanf("%d",&n)!=EOF){
		input();
	}
}
时间: 2024-10-17 10:43:47

hdu 2896 AC自动机的相关文章

HDU 2896 AC自动机 + 细心

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

HDU 2896 (AC自动机模板题)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2896 题目大意:多个模式串.多个匹配串.其中串的字符范围是(0~127).问匹配串中含有哪几个模式串. 解题思路: AC自动机模板题.注意一下字符范围. cnt记录这个模式串的个数改为这个模式串的index. find的时候,把找到的index压入vector里面即可. 注意有多个匹配串,每次find之后会把last->cnt修改,原因是防止一个模式串出现了多次被压入vector,所以先备份一下,

HDU 2896 ac自动机裸题

病毒侵袭 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻....在这样的时刻,人们却异常兴奋――我们能在有生之年看到500年一遇的世界奇观,那是多么幸福的事儿啊~~ 但网路上总有那么些网站,开始借着民众的好奇心,打着介绍日食的旗号,大肆传播病毒.小t不幸成为受害者之一.小t如此生气,他决定要把世界上所有

hdu 2296 aC自动机+dp(得到价值最大的字符串)

Ring Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3180    Accepted Submission(s): 1033 Problem Description For the hope of a forever love, Steven is planning to send a ring to Jane with a rom

hdu 2457 AC自动机+dp

DNA repair Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2004    Accepted Submission(s): 1085 Problem Description Biologists finally invent techniques of repairing DNA that contains segments c

hdu 2825 aC自动机+状压dp

Wireless Password Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5640    Accepted Submission(s): 1785 Problem Description Liyuan lives in a old apartment. One day, he suddenly found that there

hdu 3065 AC自动机(各子串出现的次数)

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

hdu 5880 AC自动机

Family View Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 175    Accepted Submission(s): 20 Problem Description Steam is a digital distribution platform developed by Valve Corporation offering

HDU 4518 ac自动机+数位dp

吉哥系列故事--最终数 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 304    Accepted Submission(s): 102 Problem Description 在2012年腾讯编程马拉松比赛中,吉哥解决了一道关于斐波那契的题目,这让他非常高兴,也更加燃起了它对数学特别是斐波那契数的热爱.现在,它又在思考一个关于斐波那契