AC自动机(Keywords Search)
题目链接:https://cn.vjudge.net/contest/280743#problem/A
题目大意:首先给你T组测试样例,然后给你n个字符串,最后再给你一个模式串,然后问你这一些字符串中是模式串的子串的有多少个?
具体思路:AC自动机模板题,先说一下各个数组的作用吧,ch数组是字典树中的数组,val也是字典树中的数组,储存的是从根节点到当前这个节点是不是有字符串。fail和last就是AC自动机中的数组了,fail数组的作用就是从根节点到当的节点形成的字符串的后缀是一个新的路径的前缀,能够在匹配失败的时候,通过指针的跳动来节省时间。last数组的作用就是在求和的时候方便记录,如果当前节点有字符串的话,直接通过指针的跳动能够避免当前节点没有字符串的情况。
AC代码:
#include<iostream>
#include<stack>
#include<stdio.h>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std;
# define ll long long
const int maxn = 2e5+;
const int maxm = 1e6+;
char str[maxm];
int tot,ch[maxn][],val[maxn];
int fail[maxn],last[maxn];
void add()
{
int p=;
int len=strlen(str);
for(int i=; i<len; i++)
{
int u=str[i]-'a';
if(!ch[p][u])
ch[p][u]=++tot;
p=ch[p][u];
}
val[p]++;
}
void getfail()
{
queue<int>q;
for(int i=; i<; i++)
{
if(ch[][i])
q.push(ch[][i]);
}
while(!q.empty())
{
int top=q.front();
q.pop();
for(int i=; i<; i++)
{
int u=ch[top][i];
if(u==)
continue;
q.push(u);
int v=fail[top];
while(v&&ch[v][i]==)
v=fail[v];
fail[u]=ch[v][i];
last[u]=val[fail[u]] ? fail[u] : last[fail[u]];
}
}
}
int cal(int t)
{
int ans=;
while(t)
{
ans+=val[t];
val[t]=;
t=last[t];
}
return ans;
}
int getans()
{
int ans=;
int len=strlen(str);
int p=;
for(int i=; i<len; i++)
{
int u=str[i]-'a';
while(p&&ch[p][u]==)
p=fail[p];
p=ch[p][u];
if(val[p])
ans+=cal(p);
else if(fail[p])
ans+=cal(fail[p]);
}
return ans;
}
void init()
{
for(int i=; i<tot; i++)
{
fail[i]=,last[i]=,val[i]=;
for(int j=; j<; j++)
{
ch[i][j]=;
}
}
tot=;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
int n;
scanf("%d",&n);
for(int i=; i<=n; i++)
{
scanf("%s",str);
add();
}
getfail();
scanf("%s",str);
int ans=getans();
printf("%d\n",ans);
}
return ;
}
AC自动机(Keywords Search)的更多相关文章
- AC自动机---Keywords Search
题目网址:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=110773#problem/A Description In the moder ...
- AC日记——Keywords Search hdu 2222
2222 思路: ac自动机模板题: 代码: #include <cstdio> #include <cstring> #include <iostream> #i ...
- 【HDU2222】Keywords Search AC自动机
[HDU2222]Keywords Search Problem Description In the modern time, Search engine came into the life of ...
- hdu2222 Keywords Search ac自动机
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=2222 题目: Keywords Search Time Limit: 2000/1000 MS ...
- HDU 2222 Keywords Search(AC自动机模版题)
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- HDU2222 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: 65536/32768 K (Java/Others)T ...
- 【HDU2222】Keywords Search(AC自动机)
Problem Description In the modern time, Search engine came into the life of everybody like Google, B ...
- HDU2222 Keywords Search(AC自动机)
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- hdu2222 Keywords Search【AC自动机】
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
随机推荐
- PAT甲题题解-1012. The Best Rank (25)-排序水题
排序,水题因为最后如果一个学生最好的排名有一样的,输出的课程有个优先级A>C>M>E那么按这个优先级顺序进行排序每次排序前先求当前课程的排名然后再与目前最好的排名比较.更新 至于查询 ...
- 黄金分割点(第五周 c语言版)
在上一周,学习其他课程的同时,用C语言编写了黄金分割点小游戏.因为要做界面需要mfc,当时学的时候还做了个简单的计算器.目前c++的知识忘的差不多了,所以就先用C语言来实现算法.打算接下来的一周复习c ...
- HDU 2020 绝对值排序
http://acm.hdu.edu.cn/showproblem.php?pid=2020 Problem Description 输入n(n<=100)个整数,按照绝对值从大到小排序后输出. ...
- mac 关闭显示器 & 快捷键
mac 关闭显示器 & 快捷键 https://support.apple.com/zh-cn/HT201236 https://support.apple.com/zh-cn/HT20705 ...
- BCB将RichEdit光标移到最后一行
int linecount=RichEdit1->Lines->Count; RichEdit1-> SelStart=SendMessage(RichEdit1-> Hand ...
- SP1043 GSS1
题目链接 简单说就是带修的查询区间最大子段和,用线段树维护即可 对于每个区间,我们肯定要记录它的最大子段和\(v\),但是怎么维护呢? 我们可以记录下从区间左端点开始的最大子段和\(v1\),从右端点 ...
- 关于链表的总结(C++循环实现)
0.目录 1.链表的基本操作 1.1 结点定义 1.2 创建链表 1.3 销毁链表 1.4 打印链表 1.5 获取链表长度 2.结点的基本操作 2.1 删除结点 2.2 查找结点 3.面试题 3.1 ...
- We Need More Bosses CodeForces - 1000E(缩点 建图 求桥 求直径)
题意: 就是求桥最多的一条路 解析: 先求连通分量的个数 然后缩点建图 求直径即可 #include <bits/stdc++.h> #define mem(a, b) memset(a ...
- 51Nod 1287 加农炮 (线段树)
1287 加农炮 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 一个长度为M的正整数数组A,表示从左向右的地形高度 ...
- 用call/cc合成所有的控制流结构
用call/cc合成所有的控制流结构 来源 https://www.jianshu.com/p/e860f95cad51 call/cc 是非常.非常特殊的,因为它根本无法用 Lambda 演算定义. ...