【算法】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. iOS开发NSDate详解

    1. 用于创建NSDate实例的类方法有 + (id)date; 返回当前时间 + (id)dateWithTimeIntervalSinceNow:(NSTimeInterval)secs; 返回以 ...

  2. week12 201621044079 流与文件

    作业12-流与文件 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 面向系统综合设计-图书馆管理系统或购物车 使用流与文件改造你的图书馆管理系统或购物车 ...

  3. Windows Server 2012四大版本介绍

    今天刚好要尝试安装Windows Server 2012,在网上百度了下发现有4个版本,分别是: Datacenter数据中心版. Standard标准版. Essentials版. Foundati ...

  4. 深入学习 Redis系列

    深入学习 Redis(1):Redis 内存模型 深入学习 Redis(2):持久化 深入学习 Redis(3):主从复制 深入学习 Redis(4):哨兵

  5. 第24天:js-函数变量声明提升

    一.函数声明1.自定义函数function fun1(){ alert("我是自定义函数");}fun2();//函数不调用,自己不执行2.直接量声明var fun2=functi ...

  6. BZOJ 1789 Y形项链(思维)

    这题类似于1787,最后的节点一定是两点的LCA,这里也就是两个字符串的最长公共前缀. # include <cstdio> # include <cstring> # inc ...

  7. CentOS7 从查看、启动、停止服务说起systemctl

    执行命令“systemctl status 服务名.service”可查看服务的运行状态,其中服务名后的.service 可以省略,这是CenOS7以后采用systemd作为初始化进程后产生的变化. ...

  8. HDU.1596 find the safest road (Floyd)

    HDU.1596 find the safest road (Floyd) 题意分析 与普通的最短路不太相同,本题有些许的变化. 1. 要找到由i到j最安全的路,故在求解的时候要保证mp[i][j]尽 ...

  9. HDU.3342 Legal or Not (拓扑排序 TopSort)

    HDU.3342 Legal or Not (拓扑排序 TopSort) 题意分析 裸的拓扑排序 根据是否成环来判断是否合法 详解请移步 算法学习 拓扑排序(TopSort) 代码总览 #includ ...

  10. SpringAOP简介

    AOP(Aspect Orient Programming) --- 面向切面编程 将分散在各个业务逻辑中的相同代码 通过 “横向”切割方式抽取到独立模块中 方式抽取到独立模块中;[它针对的是程序运行 ...