4327: JSOI2012 玄武密码
4327: JSOI2012 玄武密码
Description
Input
Output
Sample Input
SNNSSNS
NNSS
NNN
WSEE
Sample Output
2
0
HINT
对于100%的数据,N<=10^7,M<=10^5,每一段文字的长度<=100。
这题虽说是板子,但也不能只用板子,是一道比较不错的AC自动机题目。首先发现多模式串,二话不说上AC自动机,但是发现只有‘E’、‘S’、‘W’、‘N’这四个字母,所以可以优化一下建立起从‘E’、‘S’、‘W’、‘N’到‘a’、‘b’、‘c’、‘d’的映射就好了,然后要查询每个串的前缀与母串的最大匹配长度,那我们就在trie树上标记母串所有的可以匹配到的位置,然后对于每一个模式串,我们就从它的trie树上进行检索,当发现第一个没有被母串匹配到的结点时,当前长度就是最大的匹配长度。另外还有一个小小的优化,如果说对于一个节点它已经被标记过了,那么它的next链上的所有点一定也被标记了,所以这时就可以直接break。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<map>
#include<queue>
#include<stack>
#include<algorithm>
#include<vector>
#define man 100005
#define maxn 10000005
using namespace std; inline int read()
{
char c=getchar();
int res=,x=;
while(c<''||c>'')
{
if(c=='-')
x=-;
c=getchar();
}
while(c>=''&&c<='')
{
res=res*+(c-'');
c=getchar();
}
return res*x;
} int n,m,tot=;
int tree[maxn][],nt[maxn],bo[maxn],f[maxn];
char a[maxn],d[],b[man][];
queue<int>q; char pd(char c)
{
if(c=='E') return d[];
else if(c=='S') return d[];
else if(c=='W') return d[];
else return d[];
} void trie(char *s)
{
int len=strlen(s),u=;
for(register int i=;i<len;i++)
{
int c=s[i]-'a';
if(!tree[u][c])
tree[u][c]=++tot;
u=tree[u][c];
}
bo[u]=;
} void bfs()
{
for(register int i=;i<=;i++)
tree[][i]=;
nt[]=;q.push();
while(q.size())
{
int u=q.front();q.pop();
for(register int i=;i<=;i++)
{
if(!tree[u][i])
tree[u][i]=tree[nt[u]][i];
else
{
int v=tree[u][i];
q.push(v);
nt[v]=tree[nt[u]][i];
}
}
}
} void find(char *s)
{
int len=strlen(s),u=,k;
for(register int i=;i<len;i++)
{
int c=s[i]-'a';
k=tree[u][c];
while(k>)
{
if(f[k]) break;//小小的优化 原理就是这个节点被标记过时,它的
f[k]=;//next链上的点也一点被标记了,所以没必要再跳一次next
k=nt[k];//链,直接break掉就好了。
}
u=tree[u][c];
}
} int ask(char *s)
{
int len=strlen(s),u=;
for(register int i=;i<len;i++)
{
int c=s[i]-'a';
u=tree[u][c];
if(!f[u]) return i;
}
return len;
} int main()
{
n=read();m=read();
d[]='a';d[]='b';d[]='c';d[]='d';
scanf("%s",a);
for(register int i=;i<n;i++)
{
a[i]=pd(a[i]);
}
for(register int i=;i<=m;i++)
{
scanf("%s",b[i]);
int len=strlen(b[i]);
for(register int j=;j<len;j++)
{
b[i][j]=pd(b[i][j]);
}
trie(b[i]);
}
bfs();
find(a);
for(register int i=;i<=m;i++)
{
printf("%d\n",ask(b[i]));
}
return ;
}
4327: JSOI2012 玄武密码的更多相关文章
- 4327: JSOI2012 玄武密码[SAM]
4327: JSOI2012 玄武密码 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 263 Solved: 112[Submit][Status] ...
- BZOJ 4327: JSOI2012 玄武密码 后缀自动机
Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) # ...
- BZOJ 4327 JSOI2012 玄武密码(后缀自动机)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4327 [题目大意] 求每个子串在母串中的最长匹配 [题解] 对母串建立后缀自动机,用每 ...
- BZOJ 4327 [JSOI2012]玄武密码 (AC自动机)
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=4327 题解: 做法挺显然,建出AC自动机之后在上面跑,标记所有走过的点,然后再进行递推 ...
- bzoj 4327: JSOI2012 玄武密码
听说这题不公开.. 那就不贴题意了 一眼看上去还以为是exkmp的裸题.. 看了数据范围,呵呵.. 多串匹配嘛.. 就用AC自动机咯,而且每个点最多也就只有$4$个孩子 用原串在AC自动机上走,碰到的 ...
- 【题解】bzoj 4327 JSOI2012 玄武密码
原题传送门 我们先对所有询问串建立AC自动机(今天洛咕上有人分不清AC自动机和自动AC机) 然后将母串在AC自动机上跑,每走到一个点x,从x点出发沿着fail指针所能到的所有前缀都是匹配成功的,暴力向 ...
- 【BZOJ4327】JSOI2012 玄武密码 AC自动机
[BZOJ4327]JSOI2012 玄武密码 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香 ...
- P5231 [JSOI2012]玄武密码
P5231 [JSOI2012]玄武密码 链接 分析: 首先对所有询问串建立AC自动机,然后扫描一遍母串,在AC自动机上走,没走到一个点,标记这个点走过了,并且它的fail树上的祖先节点也可以访问到( ...
- 2021.11.10 P5231 [JSOI2012]玄武密码(AC自动机)
2021.11.10 P5231 [JSOI2012]玄武密码(AC自动机) https://www.luogu.com.cn/problem/P5231 题意: 给出字符串S和若干T,求S与每个T的 ...
随机推荐
- Python基础:数据类型-列表与元组(6)
Python中数据结构主要有序列.集合和字典. 1. 通用序列操作 Python内置了多种序列,其中最常用的两种:列表和元组.另一种重要的序列是字符串. 列表和元组的主要不同在于:列表是可以修改的,而 ...
- 【pytorch】关于Embedding和GRU、LSTM的使用详解
1. Embedding的使用 pytorch中实现了Embedding,下面是关于Embedding的使用. torch.nn包下的Embedding,作为训练的一层,随模型训练得到适合的词向量. ...
- [2019.03.22] Linux 学习心得(1)
本文关键词:shell 判断.grep正则表达式使用和贪婪匹配理解 1. if [ $a -le $b ], 一开始自学的时候我以为 [ ... ] 就是普通的,语法规定的结构,结果其实人家是&quo ...
- Excel中最精确的计算年龄的公式
身份证算年龄 假设A1是身份证号所在单元格 =IF(MONTH(NOW())<INT(MID(A1,11,2)),INT(YEAR(NOW())-INT(MID(A1,7,4)))-1,IF(M ...
- MySQL数据库开发的三十六条军规
一.核心军规 尽量不在数据库做运算,cpu计算的事务必移至业务层; 控制表.行.列数量([控制单张表的数据量 1年/500W条,超出可做分表],[单库表数据量不超过300张] .[单张表的字段个数不超 ...
- shc & unshc 安装
shc & unshc 安装 shc 安装 git clone https://github.com/neurobin/shc.git cd shc ./configure make & ...
- Python3 找不到库
import sys sys.path.append('/usr/local/lib64/python3.6/site-packages')sys.path.append('/usr/local/li ...
- C#面向对象基本概念总结
快过年了,发一篇自己的复习总结.以下内容均是个人理解,如文章有幸被浏览,如有错误的地方欢迎大家提出,相互学习相互进步! 面向对象三大基本特征:封装,继承,多态 一.类 (对象声明的三种方式:以普通基类 ...
- server.xml配置介绍
server.xml位于$TOMCAT_HOME/conf目录下,是Tomcat中最重要的配置文件,server.xml的每一个元素都对应了Tomcat中的一个组件:通过对xml文件中元素的配置,可以 ...
- PLSQL Developer中文乱码问题
前言 使用PLSQL工具进行连接远程oracle时,中文乱码 解决过程 1 查看服务器端编码 select userenv('language') from dual; 2 查看客户端编码 执行语句 ...