洛谷 P3808 【模板】AC自动机(简单版)
传送门:https://www.luogu.org/problem/P3808
题解:是一个AC自动机的裸题了,注释加在代码里面了
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 5, sigma_size = 26;
int ch[maxn][sigma_size];
int tot; //结点总数
int ans = 0;
int f[maxn]; //失配函数
int last[maxn];//表示 i沿着失配指针往回走时,遇到的下一个单词结点(即是该单词的最后一个结点)的编号
int val[maxn]; //若值不为0表示该结点是单词的最后一个结点
char a[maxn];
char b[maxn];
void init()
{
tot = 1;
memset(val, 0, sizeof(val));
memset(ch, 0, sizeof(ch));
memset(f, 0, sizeof(f));
memset(last, 0, sizeof(last));
}
void insert(char *str)//将所有模式串构建成一个字典树
{
int p = 0;
int len = strlen(str);
for(int i = 0; i < len; i++)
{
int c = str[i] - 'a';
if(!ch[p][c])
{
ch[p][c] = tot++;
}
p = ch[p][c];
}
val[p] ++;//标记此结点为末尾 同时代表模式串中 相同的字符串有几个
}
void find(char *str)
{
int n = strlen(str);
int u = 0;
for(int i = 0; i < n; i++)
{
int s = str[i] - 'a';
while(u && !ch[u][s])
u = f[u];
u = ch[u][s];
if(val[u])
{
ans += val[u];
val[u] = 0;
}
else if(val[last[u]])//判断是否为单词的末尾结点
{
ans += val[last[u]];
val[last[u]] = 0;
}
}
}
void getfail()//通过BFS进行计算fail函数
{
queue<int> q;
f[0] = 0;
for(int c = 0; c < sigma_size; c++)
{
int u = ch[0][c];
if(u)//将所有根结点的孩子结点全部压入队列
{
f[u] = 0;//根结点的孩子结点失配只能跳到根结点
q.push(u);
last[u] = 0;
}
}
while(!q.empty())
{
int r = q.front();
q.pop();
for(int c = 0; c < sigma_size; c++)
{
int u = ch[r][c];
if(!u)
continue;//{ch[r][c]=ch[f[r]][c];continue}(则可以把while语句删除),路径压缩
q.push(u);
int v = f[r];
while(v && !ch[v][c])//沿着失配边走 直到可以匹配 和KMP类似
v = f[v];
f[u] = ch[v][c];
last[u] = val[f[u]] ? f[u] : last[f[u]];//last需要指向单词末尾 用val数组判断
}
}
}
int main(void)
{
int n;
scanf("%d", &n);
init();
for(int i = 1; i <= n; i++)
{
scanf("%s", a);
insert(a);//根据情况而定 还可以改为insert(a,value) ;表示该单词的权重
}
getfail();
scanf("%s", b);
find(b);
cout << ans << endl;
return 0;
}
洛谷 P3808 【模板】AC自动机(简单版)的更多相关文章
- 洛谷P3808 & P3796 AC自动机模板
题目:P3808:https://www.luogu.org/problemnew/show/P3808 P3796:https://www.luogu.org/problemnew/show/P37 ...
- 洛谷 - P3966 - 单词 - AC自动机
https://www.luogu.org/problemnew/show/P3966 因为文本串就是字典本身,所以这个和平时的AC自动机不太一样.平时的query要沿着fail树把子树的出现次数依次 ...
- [模板][P3808]AC自动机(简单版)
Description: 求n个模式串中有几个在文本串中出现 Solution: 模板,详见代码: #include<bits/stdc++.h> using namespace std; ...
- 洛谷.3121.审查(AC自动机 链表)
题目链接 //删掉一个单词需要前移一段位置,用链表维护就好了 复杂度O(sum(len)) #include <cstdio> #include <cstring> #defi ...
- 洛谷 - P2444 - 病毒 - AC自动机
https://www.luogu.org/problemnew/show/P2444 有点恶心,不太明白fail的意义. #include<bits/stdc++.h> using na ...
- 洛谷 P3804 [模板] 后缀自动机
题目:https://www.luogu.org/problemnew/show/P3804 模仿了一篇题解,感觉很好写啊. 代码如下: #include<cstdio> #include ...
- 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)
To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...
- 洛谷P3808 【模板】AC自动机(简单版)
题目背景 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次, ...
- 【刷题】洛谷 P3808 【模板】AC自动机(简单版)
题目背景 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次, ...
随机推荐
- weex框架
weex优势: (1)支持ES6规范 (2)性能优异,开发简介标准,提及小巧. (3)跨平台 weex调试工具:weexplayground weex环境搭建: (1)安装 node.js.npm ( ...
- 洛谷 P2004 领地选择
题目传送门 解题思路: 二维前缀和. AC代码: #include<iostream> #include<cstdio> using namespace std; ][],an ...
- storm on yarn安装时 提交到yarn失败 failed
最近在部署storm on yarn ,部署参考文章 http://www.tuicool.com/articles/BFr2Yvhttp://blog.csdn.net/jiushuai/artic ...
- Discuz中常用的编辑器代码
.[ b]文字:在文字的位置可以任意加入您需要的字符,显示为粗体效果. .[ i]文字:在文字的位置可以任意加入您需要的字符,显示为斜体效果. .[ u]文字:在文字的位置可以任意加入您需要的字符,显 ...
- ubuntu安装opencv3.2
把master分支git下来: git clone git@github.com:opencv/opencv.git 查看可用的版本: git tag 选择自己想要的版本号: git reset -- ...
- json解析精度问题
由于后台传过来的值是float或者double类型,解析之后作为对象放到字典或数组里面,被转成nsstring或者nsnumber会有一定的误差,很正常 解决办法,通过NSNumberFormatte ...
- repr. str, ascii in Python
repr和str a="Hello" print(str(a)) print(repr(a)) 结果: Hello 'Hello' 可以看出,repr的结果中多了左右两个引号. r ...
- CodeForces - 748C Santa Claus and Robot
题意:机器人在网格线上行走,从p1点开始,沿最短路径到p2,再沿最短路径到p3,依此类推.在此过程中留下了行走的运动轨迹,由“RLDU”表示.问若只给出运动轨迹,求最少的pi点的个数. 分析:pi到p ...
- POJ 1731:Orders
Orders Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 9940 Accepted: 6048 Descriptio ...
- trove database功能总结
我曾经以为trove只负责数据库(datastore)的部署,最近才发现trove可以进行数据库(database)的创建. 首先是列出某个实例上(instance)数据库(datastrore)上的 ...