洛谷 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,在保证正确的基础上只有两组数据,请不要恶意提交. 管理员提示:本题数据内有重复的单词,且重复单词应该计算多次, ...
随机推荐
- springboot关闭whitelabel Error page
当访问不存在的页面时报错: 如何关闭它?有2种方法, 方法1: application.properties中加入server.error.whitelabel.enabled=false 方法2:在 ...
- Webpack - 把json文件打包进js文件
把html文件打包进index.js 1 新建文件 typings.d.ts declare module "*.html" { const content: st ...
- 洛谷 P2370 yyy2015c01的U盘
题目传送门 解题思路: 先将每个文件按照占空间从小到大排序,然后跑背包,当到了某一个文件时,价值够了,那么当前文件的体积就是答案. 其实本题是可以二分答案的,但是写挂了... AC代码: #inclu ...
- 17 ~ express ~ 分类的显示 ,修改 和 删除
一,前台显示 /views/admin/category.html {% extends 'layout.html' %} {% block main %} <ol class="br ...
- Toolbar融入状态栏实现沉浸式遇到的问题
这里写一个纠结我一下午的问题,目的是写一个toolbar和状态栏相融合的沉浸式的样子,遇到各种各样的问题,还好最后慢慢解决了. 一.首先在活动中将状态栏设为透明 @Override protected ...
- 爬虫(十八):Scrapy框架(五) Scrapy通用爬虫
1. Scrapy通用爬虫 通过Scrapy,我们可以轻松地完成一个站点爬虫的编写.但如果抓取的站点量非常大,比如爬取各大媒体的新闻信息,多个Spider则可能包含很多重复代码. 如果我们将各个站点的 ...
- python复习——数据输入输出
标准输入:x=input()…… 标准输出:print()…… 格式化输出:1.字符串格式化运算符% 例:print('Values are %s,%s,%s.'%(1,2,['one','two'] ...
- 为什么 execute(`echo 中文`) 输出中文源码?
为什么 execute(echo 中文) 输出中文源码? import win.ui; /*DSG{{*/ var winform = win.form(text="管道演示";r ...
- CodeForces - 748F Santa Clauses and a Soccer Championship
题意:有k对队伍,每对队伍之间将举行两次比赛,两支队伍各主办一次.住宿的地方要求在两支队伍家乡的最短路的结点上或者在两支队伍的家乡.问在选择住宿处最少的情况下,怎么组成这k对队伍? 分析: 1.因为n ...
- BZOJ [Cqoi2017] 小Q的棋盘
题解:枚举最后在哪里停止,然后剩下的步数/2 也就是找最大深度 枚举终止位置算是一种思路吧 #include<iostream> #include<cstdio> #inclu ...