ac自动机暴力跳fail匹配——hdu5880
很简单的题,ac自动机里再维护一个len表示每个状态的串长,用s去query时每到一个结点都要暴力跳fail,因为有可能这个结点不是,但是其fail是危险结点,找到一个就直接break
再用个差分数组快速统计覆盖情况即可
using namespace std;
#define N 1000005 char s[N],t[N];
int n,cnt[N]; struct Trie{
int nxt[N][],fail[N],end[N],Len[N];
int root,L;
int newnode(){
memset(nxt[L],-,sizeof nxt[L]);
end[L]=;
return L++;
}
void init(){
L=;
root=newnode();
}
void insert(char buf[]){
int len=strlen(buf);
int now=root;
for(int i=;i<len;i++){
if(nxt[now][buf[i]-'a']==-)
nxt[now][buf[i]-'a']=newnode();
now=nxt[now][buf[i]-'a'];
}
end[now]++;Len[now]=len;
}
void build(){
queue<int>q;
fail[root]=root;
for(int i=;i<;i++)
if(nxt[root][i]==-)
nxt[root][i]=root;
else {
fail[nxt[root][i]]=root;
q.push(nxt[root][i]);
}
while(q.size()){
int now=q.front();
q.pop();
for(int i=;i<;i++)
if(nxt[now][i]==-)
nxt[now][i]=nxt[fail[now]][i];
else {
fail[nxt[now][i]]=nxt[fail[now]][i];
q.push(nxt[now][i]);
}
}
} void query(char *s){
int now=root;
int len=strlen(s);
for(int i=;i<len;i++){
if(s[i]<'a' || s[i]>'z'){
now=root;continue;
}
now=nxt[now][s[i]-'a'];
int p=now;
while(p){
if(end[p]){//遇到危险结点了
cnt[i+]--;
cnt[i-Len[p]+]++;
break;
}
p=fail[p];
}
}
}
}ac; int main(){
int tt;cin>>tt;while(tt--){
ac.init();
cin>>n;
for(int i=;i<=n;i++){
scanf("%s",s);
ac.insert(s);
}
ac.build(); char ch;
int len=;
getchar();
scanf("%[^\n]%*c",s);
len=strlen(s); for(int i=;i<len;i++){
t[i]=s[i];
if(s[i]>='A' && s[i]<='Z')
s[i]+='a'-'A';
}
t[len]=; for(int i=;i<=len;i++)cnt[i]=;
ac.query(s);
for(int i=;i<len;i++)cnt[i]+=cnt[i-];
for(int i=;i<len;i++){
if(cnt[i]>=)printf("*");
else printf("%c",t[i]);
} puts("");
}
}
ac自动机暴力跳fail匹配——hdu5880的更多相关文章
- AC自动机——多个kmp匹配
(并不能自动AC) 介绍: Aho-Corasick automaton,最经典的处理多个模式串的匹配问题. 是kmp和字典树的结合. 精髓与灵魂: ①利用trie处理多个模式串 ②引入fail指针. ...
- 洛谷P2414 阿狸的打字机【AC自动机】【fail树】【dfs序】【树状数组】
居然真的遇上了这种蔡队题.瑟瑟发抖. 题目背景 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机. 题目描述 打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿 ...
- [NOI2011][bzoj2434] 阿狸的打字机 [AC自动机+dfs序+fail树+树状数组]
题面 传送门 正文 最暴力的 最暴力的方法:把所有询问代表的字符串跑一遍kmp然后输出 稍微优化一下:把所有询问保存起来,把模板串相同的合并,求出next然后匹配 但是这两种方法本质没有区别,都是暴力 ...
- 【洛谷】3966:[TJOI2013]单词【AC自动机】【fail树】
P3966 [TJOI2013]单词 题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 输入输出 ...
- Codeforces 590E - Birthday(AC 自动机+Dilworth 定理+二分图匹配)
题面传送门 AC 自动机有时只是辅助建图的工具,真的 首先看到多串问题,果断建出 AC 自动机.设 \(m=\sum|s_i|\). 不难发现子串的包含关系构成了一个偏序集,于是我们考虑转化为图论,若 ...
- AC 自动机学习笔记
虽然 NOIp 原地爆炸了,目前进入 AFO 状态,但感觉省选还是要冲一把,所以现在又来开始颓字符串辣 首先先复习一个很早很早就学过但忘记的算法--自动 AC AC自动机. AC 自动机能够在 \(\ ...
- BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机、树状数组)
吐槽: 为啥很多人用AC自动机暴力跳都过了?复杂度真的对么? 做法一: AC自动机+树状数组 姓名的问题,中间加个特殊字符连起来即可. 肯定是对点名串建AC自动机(map存儿子),然后第一问就相当于问 ...
- BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机+map维护Trie树)
题目大意:略 由于字符集大,要用map维护Trie树 并不能用AC自动机的Trie图优化,不然内存会炸 所以我用AC自动机暴跳fail水过的 显然根据喵星人建AC自动机是不行的,所以要根据问题建 然而 ...
- ac自动机fail树上按询问建立上跳指针——cf963D
解法看着吓人,其实就是为了优化ac自动机上暴力跳fail指针.. 另外这题对于复杂度的分析很有学习价值 /* 给定一个母串s,再给定n个询问(k,m) 对于每个询问,求出长度最小的t,使t是s的子串, ...
随机推荐
- c# 7.0新语法特性
public class NewAtturibute { public void TestFunc() { // 01 Out变量 不用初始化 "; if (int.TryParse(inp ...
- boost库:字符串处理
使用boost库的字符串处理之前,需要进行区域设置.类:std::locale,每个C++程序自动拥有一个此类的实例,不能直接访问全局区域设置. 全局区域设置可以使用类std::locale中的静态函 ...
- yum工具入门
一yum介绍 注意学完了yum之后,rpm的使用频率就少了.有些功能yum用起来不如rpm更方便. CentOS: yum, dnfYUM: Yellowdog Update Modifier,rpm ...
- selenuim模块的使用 解析库
selenium: 是自动化测试工具,我们可以用它来进行爬虫. 可以驱动浏览器,执行自定义好的任务. 可以执行js代码 执行速度慢,效率低. 一般用于做登录的认证 基本选择器: find_elemen ...
- Java中如何修改Jar中的内容
一.摘要 好长时间没写blog了,之前换了一家公司.表示工作更有战斗力了,可惜就是没时间写文章了.在这段时间其实是遇到很多问题的,只是都是记录下来,并没有花时间去研究解决.但是这周遇到这个问题没办法让 ...
- 75、python学习第一篇
1.sys包下边的argv方法,从控制台获取数据 ''' Created on 2017年4月8日 @author: weizhen ''' import sys One = [" * &q ...
- Python Numpy线性代数操作
Python Numpy线性代数函数操作 1.使用dot计算矩阵乘法 import numpy as np from numpy import ones from __builtin__ import ...
- vue实现轮播效果
vue实现轮播效果 效果如下:(不好意思,图有点大:) 功能:点击左侧图片,右侧出现相应的图片:同时左侧边框变颜色. 代码如下:(也可以直接下载文件) <!DOCTYPE html> &l ...
- 如何用QTP录制鼠标右键点击事件
QTP录制鼠标右键单击事件要通过模拟键盘操作来实现 Step 1,修改ReplayType为2,一般情况默认设置是1的.(1 – 使用浏览器事件运行鼠标操作. 2 – 使用鼠标运行鼠标操作)Setti ...
- EF复合主键
[Key,Column(Order = )] [Key,Column(Order = )]