【HDU】2222 Keywords Search
【算法】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 ;
}
【HDU】2222 Keywords Search的更多相关文章
- 【HDU】2222 Keywords Search(AC自动机)
题目 传送门:QWQ 分析 $ AC $自动机模板,黈力的码风真的棒极了,这是我抄他的. 还有 题号不错 代码 #include <cstdio> #include <cstring ...
- 【HDOJ】2222 Keywords Search
AC自动机基础题. #include <iostream> #include <cstdio> #include <cstring> #include <cs ...
- HDU 2222 Keywords Search(查询关键字)
HDU 2222 Keywords Search(查询关键字) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K ...
- 【HDU】4888 Redraw Beautiful Drawings 网络流【推断解是否唯一】
传送门:pid=4888">[HDU]4888 Redraw Beautiful Drawings 题目分析: 比赛的时候看出是个网络流,可是没有敲出来.各种反面样例推倒自己(究其原因 ...
- AC自动机 HDOJ 2222 Keywords Search
题目链接 题意:每个文本串的出现次数 分析:入门题,注意重复的关键字算不同的关键字,还有之前加过的清零. 新模板,加上last跑快一倍 #include <bits/stdc++.h> ...
- 【刷题】HDU 2222 Keywords Search
Problem Description In the modern time, Search engine came into the life of everybody like Google, B ...
- hdoj 2222 Keywords Search 【AC自己主动机 入门题】 【求目标串中出现了几个模式串】
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- HDU 2222 Keywords Search(AC自动机模版题)
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- HDU 2222 Keywords Search(瞎搞)
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
随机推荐
- Alpha冲刺——第二天
Alpha第二天 听说 031502543 周龙荣(队长) 031502615 李家鹏 031502632 伍晨薇 031502637 张柽 031502639 郑秦 1.前言 任务分配是VV.ZQ. ...
- 分页查询es时,返回的数据不是自己所期望的问题
在进行es分页查询时,一般都是用sql语句转成es查询字符串,在项目中遇到过不少次返回的数据不是自己所期望的那样时,多半原因是自己的sql拼接的有问题. 解决办法:务必要保证自己的sql语句拼接正确.
- lintcode-172-删除元素
172-删除元素 给定一个数组和一个值,在原地删除与值相同的数字,返回新数组的长度. 元素的顺序可以改变,并且对新的数组不会有影响. 样例 给出一个数组 [0,4,4,0,0,2,4,4],和值 4 ...
- iOS-创建UIScrollerView(封装UIScrollerView)
创建继承于UIView的类WJImageScrollView,代码实现如下: WJImageScrollView.h #import <UIKit/UIKit.h> /**点击图片bloc ...
- HDU 1995 R-汉诺塔V
https://vjudge.net/contest/67836#problem/R 用1,2,...,n表示n个盘子,称为1号盘,2号盘,....号数大盘子就大.经典的汉诺塔问 题经常作为一个递归的 ...
- P1086 花生采摘
题目描述 鲁宾逊先生有一只宠物猴,名叫多多.这天,他们两个正沿着乡间小路散步,突然发现路边的告示牌上贴着一张小小的纸条:“欢迎免费品尝我种的花生!――熊字”. 鲁宾逊先生和多多都很开心,因为花生正是他 ...
- AOP拦截+权限验证+返回默认接口对象
接口如:public IList<string> TestAOP(string token); public IMethodReturn Invoke(IMethodInvocation ...
- BZOJ3437 小P的牧场 【斜率优化dp】
3437: 小P的牧场 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1502 Solved: 836 [Submit][Status][Disc ...
- Mac将应用拖入Finder工具栏
在Finder的工具栏上放一下应用,方便打开对应的文件,可以 Command + 鼠标拖动应用,将应用拖入Finder工具栏中. 本人的Finder工具栏上添加了vscode这个应用
- 手动实现一个简易版SpringMvc
版权声明:本篇博客大部分代码引用于公众号:java团长,我只是在作者基础上稍微修改一些内容,内容仅供学习与参考 前言:目前mvc框架经过大浪淘沙,由最初的struts1到struts2,到目前的主流框 ...