TZOJ 5986 玄武密码(AC自动机)
描述
在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河。相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中。老人们说,这是玄武神灵将天书藏匿在此。
很多年后,人们终于在进香河地区发现了带有玄武密码的文字。更加神奇的是,这份带有玄武密码的文字,与玄武湖南岸台城的结构有微妙的关联。于是,漫长的破译工作开始了。
经过分析,我们可以用东南西北四个方向来描述台城城砖的摆放,不妨用一个长度为N的序列来描述,序列中的元素分别是‘E’,‘S’,‘W’,‘N’,代表了东南西北四向,我们称之为母串。而神秘的玄武密码是由四象的图案描述而成的M段文字。这里的四象,分别是东之青龙,西之白虎,南之朱雀,北之玄武,对东南西北四向相对应。
现在,考古工作者遇到了一个难题。对于每一段文字,其前缀在母串上的最大匹配长度是多少呢?
输入
第一行有两个整数,N和M,分别表示母串的长度和文字段的个数。
第二行是一个长度为N的字符串,所有字符都满足是E,S,W和N中的一个。
之后M行,每行有一个字符串,描述了一段带有玄武密码的文字。依然满足,所有字符都满足是E,S,W和N中的一个。
对于100%的数据,N<=10^7,M<=10^5,每一段文字的长度<=100。
输出
输出有M行,对应M段文字。
每一行输出一个数,表示这一段文字的前缀与母串的最大匹配串长度。
样例输入
7 3
SNNSSNS
NNSS
NNN
WSEE
样例输出
4
2
0
题意
如上。
题解
M个串建AC自动机,由于只有ESWN四个字符,所以只用开4,记录串i在AC自动机最后的位置id,并且记录父节点father和深度d。
查询S所能到达的所有节点,标记vis。
最后串i最后的位置id往上跑,如果已经被标记输出dis。
时间复杂度O(N+100*M)。
代码
#include<bits/stdc++.h>
using namespace std; const int N=1e7+,M=1e5+;
int tot,son[N][],father[N],fail[N],q[N],d[N],id[M];
int n,m;char s[N],s1[N];
bool vis[N];
inline int get(char ch){
if(ch=='E')return ;
else if(ch=='S')return ;
else if(ch=='W')return ;
else return ;
}
void insert(int p){
for(int l=strlen(s),x=,i=,w;i<l;i++){
if(!son[x][w=get(s[i])])son[x][w]=++tot;
father[son[x][w]]=x;d[son[x][w]]=d[x]+;x=son[x][w];
if(i==l-)id[p]=x;
}
}
void make(){
int h=,t=,i,j,x;fail[]=-;
for(i=;i<;i++)if(son[][i])q[++t]=son[][i];
while(h<=t)for(x=q[h++],i=;i<;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 find(){
for(int l=n,x=,i=,j;i<l;i++){
x=son[x][get(s1[i])];
for(j=x;j;j=fail[j])vis[j]=;
}
}
int dfs(int u){
for(int i=u;i>;i=father[i])
if(d[i]&&vis[i])return d[i];
return ;
}
int main()
{
scanf("%d%d%s",&n,&m,s1);
for(int i=;i<=m;i++)scanf("%s",s),insert(i);
make();
find();
for(int i=;i<=m;i++)printf("%d\n",dfs(id[i]));
return ;
}
TZOJ 5986 玄武密码(AC自动机)的更多相关文章
- 【BZOJ4327】JSOI2012 玄武密码 AC自动机
[BZOJ4327]JSOI2012 玄武密码 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香 ...
- BZOJ4327 [JSOI2012] 玄武密码 [AC自动机]
题目传送门 玄武密码 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老人们说,这是玄武神 ...
- Vijos P1951 玄武密码 (AC自动机)
描述 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老人们说,这是玄武神灵将天书藏匿在此. 很多年后,人们终于在 ...
- BZOJ 4327 [JSOI2012]玄武密码 (AC自动机)
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=4327 题解: 做法挺显然,建出AC自动机之后在上面跑,标记所有走过的点,然后再进行递推 ...
- BZOJ_4327_JSOI2012 玄武密码_AC自动机
BZOJ_4327_JSOI2012 玄武密码_AC自动机 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便 ...
- BZOJ 1559: [JSOI2009]密码( AC自动机 + 状压dp )
建AC自动机后, dp(x, y, s)表示当前长度为x, 在结点y, 包括的串的状态为s的方案数, 转移就在自动机上走就行了. 对于输出方案, 必定是由给出的串组成(因为<=42), 所以直接 ...
- [JSOI2009]密码 [AC自动机]
题面 bzoj luogu 首先看到这题就知道随便暴枚 只要是多项式算法都能过 先常规建AC自动机 注意被别的单词包含的单词没有存在的价值 剩余单词状压 大力dp f[长度][节点编号][状态] \( ...
- BZOJ1559[JSOI2009]密码——AC自动机+DP+搜索
题目描述 输入 输出 样例输入 10 2 hello world 样例输出 2 helloworld worldhello 提示 这题算是一个套路题了,多个串求都包含它们的长为L的串的方案数. 显然是 ...
- [BZOJ1559]密码 AC自动机+状压
问题 K: [JSOI2009]密码 时间限制: 1 Sec 内存限制: 64 MB 题目描述 众所周知,密码在信息领域起到了不可估量的作用.对于普通的登陆口令,唯一的破解 方法就是暴力破解一逐个尝 ...
随机推荐
- 【转载】flex布局超过显示省略号
<div class="main"> <div class="content"> <h4 class="name&quo ...
- 一个mdl相关的问题
感觉挺有意义的,细节问题 http://www.kernelmode.info/forum/viewtopic.php?f=14&t=4318这个人代码到底犯了什么错误 I want to p ...
- vue qs插件的使用
参考:https://blog.csdn.net/weixin_43851769/article/details/86505164 qs 是一个增加了一些安全性的查询字符串解析和序列化字符串的库. 步 ...
- 编写Reduce处理逻辑
- MapReduce的体系结构
- Excel skill: 如何替换换行符,以及如何把一格转换成多行/多列
http://blog.sciencenet.cn/blog-508298-695290.html 增加一辅助列,用替换函数替换掉软回车.比如A列是数据,从A1开始,则插入B列,B1输入公式=REPL ...
- re模块补充
)# 后面加数字代表前面多少个进行替换print(ret8) # stars466c7#7.subn() 会返回替换了多少次ret9=re.subn('\d','asd','sh8sd6sds7smm ...
- 【转载】linux进程及进程控制
Linux进程控制 程序是一组可执行的静态指令集,而进程(process)是一个执行中的程序实例.利用分时技术,在Linux操作系统上同时可以运行多个进程.分时技术的基本原理是把CPU的运行时间划 ...
- ThinkPHP 删除数据
ThinkPHP删除数据使用delete方法,例如: 直线电机价格 $Form = M('Form'); $Form->delete(5); 表示删除主键为5的数据,delete方法可以删除单个 ...
- centos7 搭建 php7 + nginx (2)
安装php php下载地址 # 避免出错,先安装下面 yum install libzip libzip-devel libxml2-devel openssl openssl-devel bzip2 ...