题目传送门

玄武密码

Description

在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河。相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中。老人们说,这是玄武神灵将天书藏匿在此。 
很多年后,人们终于在进香河地区发现了带有玄武密码的文字。更加神奇的是,这份带有玄武密码的文字,与玄武湖南岸台城的结构有微妙的关联。于是,漫长的破译工作开始了。 
经过分析,我们可以用东南西北四个方向来描述台城城砖的摆放,不妨用一个长度为N的序列来描述,序列中的元素分别是‘E’,‘S’,‘W’,‘N’,代表了东南西北四向,我们称之为母串。而神秘的玄武密码是由四象的图案描述而成的M段文字。这里的四象,分别是东之青龙,西之白虎,南之朱雀,北之玄武,对东南西北四向相对应。 
现在,考古工作者遇到了一个难题。对于每一段文字,其前缀在母串上的最大匹配长度是多少呢? 
 

Input

第一行有两个整数,N和M,分别表示母串的长度和文字段的个数。 
第二行是一个长度为N的字符串,所有字符都满足是E,S,W和N中的一个。 
之后M行,每行有一个字符串,描述了一段带有玄武密码的文字。依然满足,所有字符都满足是E,S,W和N中的一个。 
 

Output

输出有M行,对应M段文字。 
每一行输出一个数,表示这一段文字的前缀与母串的最大匹配串长度。 
 

Sample Input

7 3
SNNSSNS
NNSS
NNN
WSEE

Sample Output

4
2
0

HINT

对于100%的数据,N<=10^7,M<=10^5,每一段文字的长度<=100。


  分析:

  AC自动机的好题。

  建Trie树的时候记录一下每个节点的父节点和每一段模式串的终点,然后建立$fail$指针再跑一边文本串,再经过了的节点打上标记,然后对每一个模式串询问,从终点一直往根节点跳,只要遇到打上标记的点就直接返回答案(也就是该模式串总长减去遍历经过的节点数)。

  Code:

//It is made by HolseLee on 13rd Aug 2018
//BZOJ4327
#include<bits/stdc++.h>
using namespace std; const int N=1e7+;
const int M=;
const int maxn=5e5+;
int n,m,tot,fail[maxn],fa[maxn],point[maxn],lo[maxn/];
char s[N],a[M];
struct Node{
int nxt[];bool vis;
}t[maxn];
queue<int>team; struct Trie{ int get(char ch)
{
if(ch=='E')return ;
if(ch=='S')return ;
if(ch=='W')return ;
if(ch=='N')return ;
} void ins(char *ch,int x)
{
int root=,k,len=strlen(ch);
for(int i=;i<len;++i){
k=get(ch[i]);
if(!t[root].nxt[k])
t[root].nxt[k]=++tot,
fa[t[root].nxt[k]]=root;
root=t[root].nxt[k];
}
point[x]=root;
} void getfail()
{
int root=;
for(int i=;i<;++i){
if(t[root].nxt[i])
fail[t[root].nxt[i]]=,
team.push(t[root].nxt[i]);
}
while(!team.empty()){
root=team.front();team.pop();
for(int i=;i<;++i)
if(t[root].nxt[i]){
fail[t[root].nxt[i]]=t[fail[root]].nxt[i];
team.push(t[root].nxt[i]);
}
else t[root].nxt[i]=t[fail[root]].nxt[i];
}
} void pre()
{
for(int i=;i<=tot;++i)t[i].vis=false;
int root=,id;
for(int i=;i<n;++i){
id=get(s[i]);
root=t[root].nxt[id];
for(int j=root;j;j=fail[j])
if(t[j].vis)break;
else t[j].vis=;
}
} int quary(int x)
{
int ret=lo[x];
for(int i=point[x];i;i=fa[i]){
if(t[i].vis)return ret;
ret--;
}
return ;
}
}T; int main()
{
scanf("%d%d%s",&n,&m,s);
for(int i=;i<=m;++i){
scanf("%s",a);
lo[i]=strlen(a);
T.ins(a,i);
}
T.getfail();T.pre();
for(int i=;i<=m;++i)
printf("%d\n",T.quary(i));
return ;
}

BZOJ4327 [JSOI2012] 玄武密码 [AC自动机]的更多相关文章

  1. 【BZOJ4327】JSOI2012 玄武密码 AC自动机

    [BZOJ4327]JSOI2012 玄武密码 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香 ...

  2. BZOJ 4327 [JSOI2012]玄武密码 (AC自动机)

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=4327 题解: 做法挺显然,建出AC自动机之后在上面跑,标记所有走过的点,然后再进行递推 ...

  3. BZOJ4327 JSOI2012玄武密码(AC自动机)

    当然可以在SA上二分答案,但看起来会被卡log.考虑对模板串建出AC自动机,用母串在上面跑,标记上所有能到达的点.注意到达某个点时需要标记所有其通过fail指针可以走到的点,如果遇到一个标记过的点就可 ...

  4. 【AC自动机】bzoj4327: JSOI2012 玄武密码

    题目思路没话讲:主要是做题时候的细节和经验 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中 ...

  5. Vijos P1951 玄武密码 (AC自动机)

    描述 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老人们说,这是玄武神灵将天书藏匿在此. 很多年后,人们终于在 ...

  6. TZOJ 5986 玄武密码(AC自动机)

    描述 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老人们说,这是玄武神灵将天书藏匿在此. 很多年后,人们终于在 ...

  7. BZOJ 4327: JSOI2012 玄武密码 后缀自动机

    Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) # ...

  8. BZOJ4327 : JSOI2012 玄武密码

    对所有询问串建立AC自动机. 然后将母串在AC自动机上跑,每走到一个点x,从x点出发沿着fail指针能到的所有前缀都是匹配成功的,暴力向上走,碰到走过的就break,这样每个点最多只会被标记一次. 时 ...

  9. BZOJ4327:[JSOI2012]玄武密码(SAM)

    Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老人们说,这是玄武神灵将天书藏匿在此.  ...

随机推荐

  1. C++ string功能补充(类型互转,分割,合并,瘦身)

    int StringUtil::intFromString(string data) { //NOTE atoi是非标准C函数 return atoi(data.c_str()); } string ...

  2. UVA 1650 Number String

    https://vjudge.net/problem/UVA-1650 题意:D表示比前一个数打,I表示比前一个数小,?表示不确定 给出一个长为n由D I?组成的字符串,问满足字符串大小要求的n+1的 ...

  3. HDU 1930 CRT

    也是很模板的一道题,给出一些数,分割,模数固定是4个互质的. /** @Date : 2017-09-16 23:54:51 * @FileName: HDU 1930 CRT.cpp * @Plat ...

  4. Linux_创建母版,快速克隆,如何移动虚拟机.ziw

    2017年1月9日, 星期一 Linux_创建母版,快速克隆,如何移动虚拟机       1. 安裝虚拟机       2. 建立母版——第一次启动虚拟机    2.1 设置网卡为NAT模式   2. ...

  5. ASP.NET中防止Access数据库下载

    如何防止Access数据库下载是一个很老的话题了,网上的讨论也比较多.这里我们给出几种在ASP.NET下防止Access数据库被下载的方法. 我们这里假设Access数据库名字为 test.mdb. ...

  6. IO流-文件拷贝

    其实文件的拷贝还是文件读取写入的应用,实际是读取此路径上的文件,然后写入到指定路径下的文件. 代码举例: import java.io.*; import java.lang.*; class Tes ...

  7. 引用类型 ( 对象定义 )——Array 类型

    本文地址:http://www.cnblogs.com/veinyin/p/7607293.html  一个数组中可以存储不同类型的值,可以混合存储数字.字符串.对象等 1 创建数组 1.1 构造函数 ...

  8. MySql 快速去重方法

    1.复制需要去重的表 CREATE TABLE 新表 LIKE 旧表 ; 2.将需要去重的字段 设置为唯一union 索引 ALTER TABLE 表名 ADD UNIQUE(`字段`); 3.复制旧 ...

  9. malloc原理和内存碎片【转】

    转自:http://www.cnblogs.com/zhaoyl/p/3820852.html 当一个进程发生缺页中断的时候,进程会陷入内核态,执行以下操作: 1.检查要访问的虚拟地址是否合法 2.查 ...

  10. python操作上级子文件

    . └── folder ├── data │ └── data.txt └── test1 └── test2 └── test.py import os '***获取当前目录***'print o ...