题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222

题意:有N(N <= 10000)个长度不超过50的模式串和一个长度不超过1e6的文本串。其中模式串可以重复。问有多少文本串在模式串中出现过。(对于相同的模式串次数仍然累加)

思路:ac自动机裸题;

KMP是先将文本串进行匹配得到失配边f[];但是并不适用于文本串较长,模式串较多的情况。因为每次查询的时间复杂度为O(n+m).n,m分别为文本串和模式串的长度;

ac自动机就是建立在Trie上,用bfs得到适配边的一个逆向过程;

即将所有的模式串建立一个状态转移,之后直接匹配文本串即可;

关键:每次看的是文本串中的当前点的后缀是那个模式串的前缀,(BFS中获得f[]的关键思想)或者就是那个模式串。之后递归打印即可;

// 358MS 32704K
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#include<stack>
#include<set>
#include<map>
#include<queue>
using namespace std;
#define rep0(i,l,r) for(int i = (l);i < (r);i++)
#define rep1(i,l,r) for(int i = (l);i <= (r);i++)
#define rep_0(i,r,l) for(int i = (r);i > (l);i--)
#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS1(a) memset(a,-1,sizeof(a))
#define MSi(a) memset(a,0x3f,sizeof(a))
#define inf 0x3f3f3f3f
#define lson l, m, rt << 1
#define rson m+1, r, rt << 1|1
typedef pair<int,int> PII;
#define A first
#define B second
#define MK make_pair
typedef __int64 ll;
template<typename T>
void read1(T &m)
{
T x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
m = x*f;
}
template<typename T>
void read2(T &a,T &b){read1(a);read1(b);}
template<typename T>
void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
template<typename T>
void out(T a)
{
if(a>) out(a/);
putchar(a%+'');
}
int T,kase = ,i,j,k,n,m;
const int sigma_size = ;
const int maxn = *+;
struct Aho_Corasick{
int ch[maxn][sigma_size];
int val[maxn],f[maxn],last[maxn],cnt[maxn];
int sz;
map<string,int> ms;
Aho_Corasick(){}
void init(){sz = ; MS0(ch[]);MS0(cnt);ms.clear();}
void Insert(char *s,int v){
int u = ,n = strlen(s);
for(int i = ;i < n;i++){
int c = s[i] -'a';
if(!ch[u][c]){
MS0(ch[sz]);
val[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = v;
ms[string(s)] = v;//使用map来对应重复出现的字符串;竟然可以强转..
}
void getFail(){
queue<int> q;
f[] = ;
//初始化队列
for(int c = ;c < sigma_size;c++){
int u = ch[][c];
if(u) { f[u] = ; q.push(u); last[u] = ;}
}
while(!q.empty()){
int r = q.front();q.pop();
for(int c = ;c < sigma_size;c++){
int u = ch[r][c];
if(!u) {ch[r][c] = ch[f[r]][c]; continue;}//实现压缩
q.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 Find(char *T){
int n = strlen(T);
int j = ;
for(int i = ;i < n;i++){
int c = T[i] - 'a';
j = ch[j][c];//直接查找即可;
if(val[j]) print(j);
else if(last[j]) print(last[j]);
}
}
void print(int j){
if(j) {
cnt[val[j]]++;
print(last[j]);
}
}
}ac;
char p[][];
char text[];
int main()
{
read1(T);
while(T--){
ac.init();
read1(n);
rep1(i,,n){
scanf("%s",p[i]);
ac.Insert(p[i],i);
}
ac.getFail();
scanf("%s",text);
ac.Find(text);
int ans = ;
rep1(i,,n){
if(ac.cnt[ac.ms[string(p[i])]]) ans++;
}
out(ans);
puts("");
}
return ;
}

hdu 2222 Keywords Search ac自动机入门的更多相关文章

  1. hdu 2222 Keywords Search——AC自动机

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2222 第一道AC自动机! T了无数边后终于知道原来它是把若干询问串建一个自动机,把模式串放在上面跑:而且只 ...

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

    学习AC自动机请戳这里:大神blog........ 自动机的模板: #include <iostream> #include <algorithm> #include < ...

  3. HDU 2222 Keywords Search (AC自动机)

    题意:就是求目标串中出现了几个模式串. 思路:用int型的end数组记录出现,AC自动机即可. #include<iostream> #include<cstdio> #inc ...

  4. hdu 2222 Keywords Search ac自动机模板

    题目链接 先整理一发ac自动机模板.. #include <iostream> #include <vector> #include <cstdio> #inclu ...

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

    <题目链接> 题目大意: 给你一些单词,和一个字符串,问你这个字符串中含有多少个上面的单词. 解题分析: 这是多模匹配问题,如果用KMP的话,对每一个单词,都跑一遍KMP,那么当单词数量非 ...

  6. hdu2222 KeyWords Search AC自动机入门题

    /** 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意:题意:给定N(N <= 10000)个长度不大于50的模式串,再给定一个长度为L ...

  7. hdu 2222 Keywords Search - Aho-Corasick自动机

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submissio ...

  8. hdoj 2222 Keywords Search(AC自动机)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 思路分析:该问题为多模式匹配问题,使用AC自动机解决:需要注意的问题是如何统计该待查询的字符串包 ...

  9. hdu 2222 Keywords Search ac自己主动机

    点击打开链接题目链接 Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Ja ...

随机推荐

  1. 文件I/O(不带缓冲)之原子操作

    一.添写至一个文件 考虑一个进程,它要将数据添加到一个文件尾端.早期的UNIX系统并不支持open的O_APPEND选项,所以程序被编写成下列形式: ) < ) /* position to E ...

  2. Apache中 RewriteRule 规则参数介绍

    Apache中 RewriteRule 规则参数介绍 摘要: Apache模块 mod_rewrite 提供了一个基于正则表达式分析器的重写引擎来实时重写URL请求.它支持每个完整规则可以拥有不限数量 ...

  3. 认识CoreData-多线程

    CoreData使用相关的技术点已经讲差不多了,我所掌握的也就这么多了.... 在本篇文章中主要讲CoreData的多线程,其中会包括并发队列类型.线程安全等技术点.我对多线程的理解可能不是太透彻,文 ...

  4. typedef的使用1——引入

    #include <stdio.h> #include <string.h> //#define _CRT_SRCURE_NO_WARNING #pragma warning( ...

  5. FIO工具常用参数

    name 可能被用于覆盖作业的名称. filename fio 通常基于该作业名称,线程编号,构成一个文件名称和位置.如果您不想让线程之间的共享文件在一个作业或作业.指定文件名都以覆盖默认的. loc ...

  6. 快递查询api(多接口方案)

    /** 本环境使用php+smarty,结合两种快递api调取快递数据 * 说明,先快递鸟调取数据,失败后再调取快递网的数据* 快递鸟 http://www.kdniao.com 快递网 http:/ ...

  7. Android的自动对焦

    1,什么是自动对焦? ---安卓的自动对焦的概念是指能够在指定的位置计算出准确的焦点位置. 这个就好像是传统意义上的手动对焦.但是google是这个意思. 2.什么是追焦? ----安卓的追焦是指FO ...

  8. linux启动报错:kernel panic - not attempted to kill init

    系统类型:CentOS 6.4(x64) 启动提示:Kernel panic - not syncing: Attempted to kill init 解决办法: 系统启动的时候,按下‘e’键进入g ...

  9. ios 兼容IPV4和IPV6网络通信

    前言: 苹果官方出了新的规定,要求新上架的app都必须单独支持ipv6-only的网络. 准备工作: 搭建IPV6测试环境:http://blog.csdn.net/potato512/article ...

  10. CSS高度塌陷

    问题描述:当父元素只包含浮动的元素的时候,且父元素没有设置高度,如果父元素设置了边框border,那么看起来子元素不在父元素之内. 比如这样: html: <div id="paren ...