【算法】AC自动机

【题解】本题注意题意是多少关键字能匹配而不是能匹配多少次,以及可能有重复单词。

询问时AC自动机与KMP最大的区别是因为建立了trie,所以对于目标串T与自动机串是否匹配只需要直接访问对应结点,而不用真的比较。

因此可以预处理出拥有对应节点的失配串,不用一次一次跑前跑去找一样的。

然后还有就是一个结点可能对应多个串,所以需要last使统计答案完整。

AC自动机的细节标注在代码里了。

AC自动机过程:

[trie]

for 长度

if(!ch[u][c])初始化,ch[u][c]=++sz;

else u=ch[u][c];

val[u]=...;

[getfail]

初始进队

队:u

  for 26(处理u点后续节点)

    if(!u)ch[x][c]=ch[p[x][c],continue;(没有该点,则考虑直接走失配直到有此点的串,由于层层前推实际上前一个即可)

    u进队;(有此点)

    int j=p[x];

    while(j>0&&!ch[j][c])j=p[j];(走失配直到有此点的串)

    p[u]=ch[j][c];(记录失配边)

    last[u]=val[p[u]]?p[u]:last[p[u]];(记录同结尾价值点)

[find]

[askans]

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxnode=,maxn=,maxlen=;
int val[maxnode],sz,ch[maxnode][],p[maxnode],last[maxnode],q[];
long long ans;
char s[maxlen];
int idx(char c){return c-'a'+;}
void trie(char s[])
{
int u=,m=strlen(s+);
for(int i=;i<=m;i++)
{
int c=idx(s[i]);
if(!ch[u][c])
{
sz++;
memset(ch[sz],,sizeof(ch[sz]));//初始化
val[sz]=;//初始化
ch[u][c]=sz;
}
u=ch[u][c];
}
val[u]++;
}
void getfail()
{
int head=,tail=;//初始队列不能有队头!
p[]=;last[]=;//trie根初始化
for(int c=;c<=;c++)
{
int u=ch[][c];
if(u){p[u]=;last[u]=;q[tail++]=u;}
}
while(head!=tail)
{
int x=q[head++];if(head>)head=;
for(int c=;c<=;c++)
{
int u=ch[x][c];
if(!u){ch[x][c]=ch[p[x]][c];continue;}//直接得到可匹配字符串,无则为0。
q[tail++]=u;if(tail>)tail=;
int j=p[x];
while(j>&&!ch[j][c])j=p[j];
p[u]=ch[j][c];
last[u]=val[p[u]]?p[u]:last[p[u]];
}
}
}
void askans(int j)
{
while(j)
{
ans+=val[j];
val[j]=;
j=last[j];
}
}
void find(char s[])
{
int m=strlen(s+);
int j=;
for(int i=;i<=m;i++)
{
int c=idx(s[i]);
j=ch[j][c];//直接得到
if(val[j])askans(j);
else if(last[j])askans(last[j]);
}
}
int main()
{
int tt;
scanf("%d",&tt);
while(tt--)
{
int n;
scanf("%d",&n);
sz=;//根节点标号为0
memset(ch[],,sizeof(ch[]));//初始化根节点即可,建树中需要会继续清理,保持有效与无效结点中间始终存在断层。
for(int i=;i<=n;i++)
{
scanf("%s",s+);
trie(s);//传过去的一定要是s,不能是s+1
}
getfail();
scanf("%s",s+);
ans=;
find(s);
printf("%lld\n",ans);
}
return ;
}

AC自动机

【HDU】2222 Keywords Search的更多相关文章

  1. 【HDU】2222 Keywords Search(AC自动机)

    题目 传送门:QWQ 分析 $ AC $自动机模板,黈力的码风真的棒极了,这是我抄他的. 还有 题号不错 代码 #include <cstdio> #include <cstring ...

  2. 【HDOJ】2222 Keywords Search

    AC自动机基础题. #include <iostream> #include <cstdio> #include <cstring> #include <cs ...

  3. HDU 2222 Keywords Search(查询关键字)

    HDU 2222 Keywords Search(查询关键字) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K ...

  4. 【HDU】4888 Redraw Beautiful Drawings 网络流【推断解是否唯一】

    传送门:pid=4888">[HDU]4888 Redraw Beautiful Drawings 题目分析: 比赛的时候看出是个网络流,可是没有敲出来.各种反面样例推倒自己(究其原因 ...

  5. AC自动机 HDOJ 2222 Keywords Search

    题目链接 题意:每个文本串的出现次数 分析:入门题,注意重复的关键字算不同的关键字,还有之前加过的清零.   新模板,加上last跑快一倍 #include <bits/stdc++.h> ...

  6. 【刷题】HDU 2222 Keywords Search

    Problem Description In the modern time, Search engine came into the life of everybody like Google, B ...

  7. hdoj 2222 Keywords Search 【AC自己主动机 入门题】 【求目标串中出现了几个模式串】

    Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

  8. HDU 2222 Keywords Search(AC自动机模版题)

    Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

  9. HDU 2222 Keywords Search(瞎搞)

    Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

随机推荐

  1. 代替iframe的方法

    $('#framecont').html('').load("pageURL"); 使用jQuery.

  2. iOS- 简单说说iOS移动客户端SQLite3的基本使用

    1.为什么要使用SQLite3? •大量数据需要存储 •管理数据,存储数据   SQLite是一种关系型数据库(也是目前移动客户端的主流数据库)     2.SQLite3的几种存储类型   a.NU ...

  3. 【Docker 命令】- push 命令

    docker push : 将本地的镜像上传到镜像仓库,要先登陆到镜像仓库 语法 docker push [OPTIONS] NAME[:TAG] OPTIONS说明: --disable-conte ...

  4. 异常--throw

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  5. echarts 画 canvas 如果在IE8下不显示图标

    网上说法很多,可能版本问题,也有说script标签位置问题(放在body中) 不过先试已下,清除option对象中多余的逗号(,) 对象的最后一个属性后不要有逗号结尾

  6. 【bzoj3754】Tree之最小方差树 最小生成树

    题目描述 给出一张无向图,求它的一棵生成树,使得选出的所有边的方差最小.输出这个最小方差. 输入 第一行两个正整数N,M 接下来M行,每行三个正整数Ui,Vi,Ci N<=100,M<=2 ...

  7. 三节点搭建openstack-Mitaka版本

    前言: 现在的云计算平台已经非常火,也非常的稳定了.像阿里云平台,百度云平台等等,今天咱们基于openstack来搭建一个云平台 注意: 本次平台搭建为三节点搭建(没有外部存储节点,所有存储为本地存储 ...

  8. 转:Scipy入门

    Scipy入门 转:http://notes.yeshiwei.com/scipy/getting_started.html 本章节主要内容来自 Getting Started .翻译的其中一部分,并 ...

  9. [洛谷P2057][SHOI2007]善意的投票

    题目大意:有$n(n\leqslant300)$个人,每个人可以选择$0$或$1$,每个人最开始有意愿,有$m(m\leqslant\dfrac{n(n-1)}2)$对好朋友.定义一次的冲突数为好朋友 ...

  10. C++中数组和vector

    本文基于邓俊辉编著<数据结构(C++语言版)(第3版)>.<C++ Primer(第5版)>以及网上的相关博文而写,博主水平有限,若有不妥处,欢迎指出. 一.数组 C++中数组 ...