hdu 2222 Keywords Search ac自动机入门

时间:2022-09-23 13:32:22

题目链接: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&lpar;AC自动机模板题&rpar;

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

  3. HDU 2222 Keywords Search &lpar;AC自动机&rpar;

    题意:就是求目标串中出现了几个模式串. 思路:用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 &lpar;AC自动机&rpar;&lpar;模板题&rpar;

    <题目链接> 题目大意: 给你一些单词,和一个字符串,问你这个字符串中含有多少个上面的单词. 解题分析: 这是多模匹配问题,如果用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&lpar;AC自动机&rpar;

    题目链接: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. Mysql 安装问题排查方法

    重启了一次服务器后,使用> mysql -u root -p登陆是出现下面的错误: ERROR 2002 (HY000): Can't connect to local MySQL server ...

  2. Jquery attr&lpar;&rpar;方法 属性赋值和属性获取

    jquery中用attr()方法来获取和设置元素属性,attr是attribute(属性)的缩写,在jQuery DOM操作中会经常用到attr(),attr()有4个表达式. 1. attr(属性名 ...

  3. &lbrack;Bhatia&period;Matrix Analysis&period;Solutions to Exercises and Problems&rsqb;PrI&period;6&period;1

    Given a basis $U=(u_1,\cdots,u_n)$ not necessarily orthonormal, in $\scrH$, how would you compute th ...

  4. 使用layer显示弹出框笔记

    $.layer({     area : ['200px','auto'], //控制层宽高.当设置为auto时,意味着采用自适应, 当然,对于宽度,并不推荐这样做.例如:area : ['310px ...

  5. 将集合类转换成DataTable

    /// <summary> /// 将集合类转换成DataTale /// </summary> /// <param name="list"> ...

  6. 【测试技术】ant中的for循环用法

    有的时候,我们希望ant中也能类似脚本语言一样进行for循环,以实现一些重复性工作.由于ant核心包并未提供此功能,所以需要下载一个扩展包扔到ant的lib目录下去.详细步骤如下: 1.下载核心包:a ...

  7. cas错误&colon;org&period;jasig&period;cas&period;client&period;validation&period;TicketValidationException&colon; No principal was found in the response from the CAS server&period;

    这个问题困扰了我好几天,最终被这个哥们解决了,具体请参考:http://www.oschina.net/question/252484_149958?sort=time

  8. spring boot无法启动,或者正常启动之后无法访问报404的解决办法

    以前用spring boot都是用idea的自动创建,或者是用的Jhipster创建的,就没有深究怎么去搭建.但是今天晚上心血来潮,想自己搭一个demo来整合一些技术,于是就花一点时间来手动搭.因为今 ...

  9. (转)fabric 一个链码如何调用另一个链码

    使用开发模式测试 可以使用~/hyfa/fabric-samples/chaincode-docker-devmode/启动fabric,具体过程略 用同一个链码注册2个服务 root@2ee7b51 ...

  10. &lpar;转&rpar; C&num;之VS自带RDLC报表学习

    原文地址:http://blog.csdn.net/hk_5788/article/details/49846905  原文工具VS2010,测试版本工具VS2013 报表是这样设计的: 看看结果: ...