洛谷.3121.审查(AC自动机 链表)
//删掉一个单词需要前移一段位置,用链表维护就好了 复杂度O(sum(len))
#include <cstdio>
#include <cstring>
#define S 26
const int N=1e5+7;
int n;
char s[N],p[N];
struct AC_Automaton
{
int cnt,son[N][S],fail[N],pos[N],q[N],dep[N];
bool val[N];
struct List
{
int l,r;
}lst[N];
void Insert(char *s)
{
int x=0;
for(int i=0,l=strlen(s),id; i<l; ++i)
{
id=s[i]-'a';
if(!son[x][id]) son[x][id]=++cnt,dep[cnt]=dep[x]+1;//这里改用一个局部int ++dep还要更慢。。大概是重复节点很多的原因
x=son[x][id];
}
val[x]=1;
}
void Build()
{
int h=0,t=0;
for(int i=0; i<S; ++i)
if(son[0][i]) fail[son[0][i]]=0, q[t++]=son[0][i];
while(h<t)
{
int x=q[h++];
for(int i=0; i<S; ++i)
if(son[x][i]) fail[son[x][i]]=son[fail[x]][i],q[t++]=son[x][i];
else son[x][i]=son[fail[x]][i];
}
}
void Query(char *s)
{
int l=strlen(s+1);
for(int i=1; i<l; ++i) lst[i].l=i-1,lst[i].r=i+1;
lst[0].r=1, lst[l].l=l-1;
for(int x=0,t,i=1; i; i=lst[i].r)
{
if(son[x][t=s[i]-'a'])
{
x=son[x][t];
if(val[x])
{
t=i;
for(int j=dep[x]; j; --j) t=lst[t].l;
lst[t].r=lst[i].r, lst[lst[i].r].l=t;
x=pos[t];
}
}
else x=0;//not x=fail[x]!
pos[i]=x;
}
for(int i=lst[0].r; i; i=lst[i].r) printf("%c",s[i]);
}
}ac;
int main()
{
scanf("%s%d",p+1,&n);
for(int i=1; i<=n; ++i) scanf("%s",s),ac.Insert(s);
ac.Build(), ac.Query(p);
return 0;
}
洛谷.3121.审查(AC自动机 链表)的更多相关文章
- 洛谷 - P3966 - 单词 - AC自动机
https://www.luogu.org/problemnew/show/P3966 因为文本串就是字典本身,所以这个和平时的AC自动机不太一样.平时的query要沿着fail树把子树的出现次数依次 ...
- 洛谷P3808 & P3796 AC自动机模板
题目:P3808:https://www.luogu.org/problemnew/show/P3808 P3796:https://www.luogu.org/problemnew/show/P37 ...
- 洛谷 - P2444 - 病毒 - AC自动机
https://www.luogu.org/problemnew/show/P2444 有点恶心,不太明白fail的意义. #include<bits/stdc++.h> using na ...
- 洛谷P3121 审查(黄金)Censoring(Gold) [USACO15FEB] AC自动机
正解:AC自动机 解题报告: 传送门! 啊我好呆啊其实就挺模板题的,,,只是要一个栈搞一下,,,然后我就不会了,,,是看了题解才get的,,,QAQ 然后写下解法趴QwQ 首先看到多串匹配不难想到AC ...
- [洛谷P3121] 审查(黄金) (AC自动机)
题目描述 FJ把杂志上所有的文章摘抄了下来并把它变成了一个长度不超过10^5的字符串S.他有一个包含n个单词的列表,列表里的n个单词记为t_1...t_N.他希望从S中删除这些单词. FJ每次在S中找 ...
- P3121 [USACO15FEB]审查(AC自动机)
题目: P3121 [USACO15FEB]审查(黄金)Censoring (Gold) 解析: 多字符串匹配,首先想到AC自动机 建立一个AC自动机 因为有删除和拼接这种操作,考虑用栈维护 顺着文本 ...
- 洛谷P1996 约瑟夫问题【链表】
题目:https://www.luogu.org/problemnew/show/P1996 题意: 约瑟夫环.每次取出第m个,第2m个...... 思路: 链表维护.[感觉很少有用到链表.]非常经典 ...
- 洛谷P3201 [HNOI2009]梦幻布丁(链表 + 启发式合并)
题目链接 给出 \(n\) 个布丁,每个补丁都有其颜色.现在有 \(m\) 次操作,每次操作将第 \(x_i\) 种颜色全部变为第 \(y_i\) 种颜色. 操作中可能会插入询问,回答目前总共有多少段 ...
- 洛谷P3201 [HNOI2009]梦幻布丁 [链表,启发式合并]
题目传送门 梦幻布丁 题目描述 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. 输入输 ...
随机推荐
- 使用密钥认证机制远程登录Linux
密钥认证机制 创建存放key的文件 1)创建目录 /root/.ssh 并设置权限 [root@localhost ~]# mkdir /root/.ssh mkdir 命令用来创建目录,以后会详细介 ...
- 嵌入式系统C编程之错误处理
前言 本文主要总结嵌入式系统C语言编程中,主要的错误处理方式.文中涉及的代码运行环境如下: 一 错误概念 1.1 错误分类 从严重性而言,程序错误可分为致命性和非致命性两类.对于致命性错误,无法执行 ...
- 深入理解CMA【转】
转自:https://www.csdn.net/article/a/2016-07-07/15839383 摘要:连续内存分配(简称CMA) 是一种用于申请大量的,并且物理上连续的内存块的方法,在LW ...
- windows系统安装jdk并设置环境变量
CLASSPATH:JDK1.5之后的版本不需要配置.安装JDK 选择安装目录 安装过程中会出现两次安装提示 .第一次是安装 jdk ,第二次是安装 jre .建议两个都安装在同一个java文件夹中的 ...
- 使用Navicat Premium对sqlserver 2008进行表、字段及用户权限的精细化管理
在一些特殊的业务场景,我们需要对数据库进行精细化的管理,比如只能授权给某用户某个表的操作权限,最小权限法则可以保障数据库最大的安全.利用navicat这个轻量化的工具可以很轻松的解决这个问题 1.通过 ...
- Android网络通信(7):NFC
Android网络通信之 NFC NFC:近场通信,是一种超近距离的无线通信技术.Android从2.3版本的SDK开始支持基于NFC通信.基于NFC的识别和通信可分为三个步骤:1.Android通过 ...
- 5种PHP创建数组的方式
在PHP以及其他程序语言程序设计中,经常会用到数组的创建,在前端开发中,js的数组创建可以由[]和new Array()直接创建和赋值.然而PHP创建数组的方法有哪些呢?在查阅资料并且网上收集整理总结 ...
- Windows下虚拟机安装Mac OS X —– VM12安装Mac OS X 10.11
____________________________________________________________________________________________________ ...
- python用来生成的包含电话号码的python代码
# -*- coding:utf-8 -*-#用python生产包含电话号码的代码temp = """arr = %sindex = %stel = ''for i in ...
- 性能测试一:jmeter基础入门
JMeter,一个100%的纯Java桌面应用,由Apache组织的开放源代码项目,它是功能和性能测试的工具.具有高可扩展性.支持Web(HTTP/HTTPS).SOAP.FTP.JAVA等多种协议的 ...