AC自动机-洛谷3121 [USACO15FEB]审查(黄金)Censoring (Gold)
https://www.luogu.org/problem/show?pid=3121#sub
首先题目看清楚
FJ注意到列表中的单词不会出现一个单词是另一个单词子串的情况,这意味着每个列表中的单词在S中出现的开始位置是互不相同的
这意味着你在找答案时,当一个节点正常访问的时候,你不用去寻找fail;
你只要在匹配失败的时候取fail就好了;
关于fail的意义,可以看我AC自动机的博客;
然后我们在造trie时,顺便把一个字符串的长度记录下来;
end=一个字符串的长度;
然后我们开2个栈;
a[]记录当前搜到那个点;
b[]记录当前搜那个char;
然后如果发现当前节点是end;
直接弹出栈顶end个元素;
更新now指针,继续搜;
好了;
有个事情要注意;
我原始的AC自动机;
void makezyy(){for(int i=0;i<26;i++)if(T[0].nxt[i])q[++r]=T[0].nxt[i];while(r>l){int x=q[++l];for(int i=0;i<26;i++)if(T[x].nxt[i]){q[++r]=T[x].nxt[i];int y=T[x].fail;while(y&&!T[y].nxt[i])y=T[y].fail;T[q[r]].fail=T[y].nxt[i];}}
}
void find(int m){int o=0;for(int i=0;i<m;i++){int x=s[i]-'a';int y=o;while(y&&!T[y].nxt[x])y=T[y].fail;o=T[y].nxt[x];a[++tot]=o;b[tot]=i;if(T[o].E){tot-=T[o].E;o=a[tot];} }
}
大家看,这个好理解,但是用了while循环,会被卡一个点;
那我们看看更优的写法;
void makezyy(){for(int i=0;i<26;i++)if(T[0].nxt[i])q[++r]=T[0].nxt[i];while(r>l){int x=q[++l];for(int i=0;i<26;i++)if(!T[x].nxt[i])T[x].nxt[i]=T[T[x].fail].nxt[i];else{q[++r]=T[x].nxt[i];T[T[x].nxt[i]].fail=T[T[x].fail].nxt[i];}}
}
void find(int m){int o=0;for(int i=0;i<m;i++){o=T[o].nxt[s[i]-'a'];a[++tot]=o;b[tot]=i;if(T[o].E){tot-=T[o].E;o=a[tot];} }
}
种方法巧妙地运用地推;
两种方法求出的fail值是相同的;
但是这种方法会无法辨别出某个节点在一开始有没有某个儿子;
因为makezyy之后空的儿子自动变成了fail;
好像还可以优化的吧;
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
struct trie{int nxt[26],fail,E;
}T[100005];
int q[100005],l,r,a[100005],b[100005],tot;
int n,m,ll;
char s[100005],c[100005];
void init(int m){int o=0;for(int i=0;i<m;i++){int x=c[i]-'a';if(!T[o].nxt[x])T[o].nxt[x]=++ll;o=T[o].nxt[x];}T[o].E=m;
}
void makezyy(){for(int i=0;i<26;i++)if(T[0].nxt[i])q[++r]=T[0].nxt[i];while(r>l){int x=q[++l];for(int i=0;i<26;i++)if(!T[x].nxt[i])T[x].nxt[i]=T[T[x].fail].nxt[i];else{q[++r]=T[x].nxt[i];T[T[x].nxt[i]].fail=T[T[x].fail].nxt[i];}}
}
void find(int m){int o=0;for(int i=0;i<m;i++){o=T[o].nxt[s[i]-'a'];a[++tot]=o;b[tot]=i;if(T[o].E){tot-=T[o].E;o=a[tot];} }
}
int main()
{scanf("%s",s);scanf("%d",&n);while(n--)scanf("%s",c),init(strlen(c));makezyy();find(strlen(s));for(int i=1;i<=tot;i++)cout<<s[b[i]];
}
转载于:https://www.cnblogs.com/largecube233/p/6797890.html
AC自动机-洛谷3121 [USACO15FEB]审查(黄金)Censoring (Gold)相关推荐
- [洛谷3121]审查
题目描述 Farmer John has purchased a subscription to Good Hooveskeeping magazine for his cows, so they h ...
- 洛谷P3122 [USACO15FEB]圈住牛Fencing the Herd(计算几何+CDQ分治)
题面 传送门 题解 题目转化一下就是所有点都在直线\(Ax+By-C=0\)的同一侧,也就可以看做所有点代入\(Ax+By-C\)之后的值符号相同,我们只要维护每一个点代入直线之后的最大值和最小值,看 ...
- 洛谷P3120 [USACO15FEB]牛跳房子(动态开节点线段树)
题意 题目链接 Sol \(f[i][j]\)表示前\(i\)行\(j\)列的贡献,转移的时候枚举从哪里转移而来,复杂度\(O(n^4)\) 然后考虑每一行的贡献,动态开节点线段树维护一下每种颜色的答 ...
- 最小生成树 洛谷P3366【模板】最小生成树 洛谷P2820 局域网
嗯... 理解生成树的概念: 在一幅图中将所有n个点连接起来的n-1条边所形成的树. 最小生成树: 边权之和最小的生成树. 最小瓶颈生成树: 对于带权图,最大权值最小的生成树. 如何操作? 1.Pri ...
- 洛谷 P-4045 密码(AC自动机+状态压缩+数位DP+乱搞)
洛谷 P-4045 密码 记AC的第一道黑题! 题意:已知一段密码包含了一些字符串,然后求满足条件的密码有多少个,数量小于42时还得全部输出 思路: 一开始WA了两个点,不知道WA的什么,索性把读入的 ...
- 洛谷 P3041 视频游戏的连击Video Game Combos(AC自动机+拓扑排序+数位DP)
洛谷 P3041 视频游戏的连击Video Game Combos 难度一般,不过这个数位DP其实应该叫做记忆化搜索 题意:玩游戏时可以通过按键组合打出combo技能:然后是已知N个combo的按键方 ...
- 洛谷P5357 - 【模板】AC自动机(二次加强版)(AC自动机+fail树)
题目链接:点击查看 题目大意:给出n个模式串,问在主串中分别出现了多少次 题目分析:如果像以往那样,在匹配的时候fail指针乱跳的话,那么是错误的AC自动机使用方法,时间复杂度也大大上升,接近于暴力的 ...
- AC自动机模板(【洛谷3808】)
题面 题目背景 这是一道简单的AC自动机模版题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交. 题目描述 给定n个模式串和1个文本串,求有多少个模式串 ...
- 【洛谷 P3041】 [USACO12JAN]视频游戏的连击Video Game Combos(AC自动机,dp)
题目链接 手写一下AC自动机(我可没说我之前不是手写的) Trie上dp,每个点的贡献加上所有是他后缀的串的贡献,也就是这个点到根的fail链的和. #include <cstdio> # ...
最新文章
- 套接字选项SO_LINGER
- 用泛型实现参数化类型
- hdu 1535 spfa
- linux和用户账户相关的系统文件
- mysql write rows_解析MYSQL BINLOG 二进制格式(5)--WRITE_ROW_EVENT
- 用户登录色一句java_SpringBoot中用SpringSecurity实现用户登录并返回其拥有哪些角色...
- 模拟监控和真实用户体验监测,选哪个?
- 如何删除所有已合并的Git分支?
- 九章算术卷第七 盈不足
- Linux下将你的程序打包成run文件
- 霍兰德SI型如何选专业?霍兰德职业兴趣测试
- Python官网无法打开解决方案
- 苹果内部应用商店批准/审核 iPhone 应用程序相关流程
- 【锂知道】锂电池基本原理解析:充电及放电机制
- C语言编程奖学金评定,C语言计算奖学金总额
- Android 应用换肤功能(白天黑夜主题切换)
- 再见python你好julia_再见,Python2。你好,Python3
- html网站统计来访人数,实现网站访问人数统计
- 深度学习 pytorch cifar10数据集训练
- 亚马逊测评系统软件搭建教程:luminati+候鸟防关联浏览器环境
热门文章
- 无法添加类型为“mimeMap”的重复集合项
- VB课本基础知识总结
- Redis 实现延迟队列?深深被折服!!
- 聊聊微服务的隔离和熔断
- UNIX:描述符和文件结构
- 网络:IP协议与寻址
- 【Linux 报错】com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure The las
- html中基本选择器的优先级,CSS_CSS中的各种选择器与样式优先级小结,优先级:由高到低(从上到下)- phpStudy...
- 数据中心建设模式变革-- 如何采用EPC模式实现快速交付?
- 阿里展示首个IDC智能机器人 实现人机合作