题目链接: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. 10 Technologies That will Shape Future Education--reference

    http://dizyne.net/technologies-that-will-shape-future-education/ Technology is on the rise and with ...

  2. Session Store

    Session Store Configuration Session Usage Flash Data Session Drivers Configuration Since HTTP driven ...

  3. lvm基础

    一.简介 LVM是 Logical Volume Manager(逻辑卷管理)的简写. LVM将一个或多个硬盘的分区在逻辑上集合,相当于一个大硬盘来使用,当硬盘的空间不够使用的时候,可以继续将其它的硬 ...

  4. mysql数据库常用语句2

    关于mysql常用语句的整理,上一篇涉及到ddl.dml以及一些简单的查询语句. 1:mysql分页查询 select * from table_name limit 5,10;   从下标为5元素查 ...

  5. Java阻塞中断和LockSupport

    在介绍之前,先抛几个问题. Thread.interrupt()方法和InterruptedException异常的关系?是由interrupt触发产生了InterruptedException异常? ...

  6. 通过SPList Definition自定义ListItem打开编辑详细页面

    在SharePoint中对列表SPList的操作里,常常希望当增加一个条目后还希望关联做一些其它的操作 而SharePoint自身提供的Item操作页面却没有那么灵活:所以通常情况下,我们专门为其提供 ...

  7. jqgrid项目使用记录/注释版/未整理/

    jqgrid项目使用笔记function loadActData(){ $("#actGridTable").clearGridData();//首先清空表格内容 var url ...

  8. Spring的servlet context和application context

    Spring lets you define multiple contexts in a parent-child hierarchy. The applicationContext.xml def ...

  9. C#学习笔记14:面向对象继承的特点和里氏转换

    面向对象: 继承:减少代码. 单根性  传递性 子类没有从父类那里继承了构造函数,只是会默认的调用父类那个无参数的构造函数 Class person { Public String Name { Ge ...

  10. android webview乱码问题

    使用 loadData方法是中文部分会出现乱码,即使指定“utf-8”.“gbk”.“gb2312”也一样. webView.getSettings().setDefaultTextEncodingN ...