【BZOJ4327】JSOI2012 玄武密码

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自动机搜几遍即可。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
const int maxn=10000010;
struct node
{
int ch[4],fail,cnt,vis,ans,dep;
}p[maxn];
int dic(char le)
{
switch(le)
{
case 'E':return 0;
case 'S':return 1;
case 'W':return 2;
case 'N':return 3;
}
}
int n,m,tot;
int Q[maxn],pos[100010];
char w[110],str[maxn];
queue<int> q;
void build()
{
int i,u,t;
q.push(1);
while(!q.empty())
{
u=q.front(),q.pop();
Q[++Q[0]]=u;
for(i=0;i<4;i++)
{
if(p[u].ch[i])
{
q.push(p[u].ch[i]);
t=p[u].fail;
while(!p[t].ch[i]&&t) t=p[t].fail;
if(t) p[p[u].ch[i]].fail=p[t].ch[i];
else p[p[u].ch[i]].fail=1;
}
}
}
}
void search()
{
int i,j,u=1,t;
p[u].vis=0;
for(i=0;i<n;i++)
{
while(!p[u].ch[dic(str[i])]&&u) u=p[u].fail;
u=p[u].ch[dic(str[i])];
u=u>0?u:1;
p[u].vis=1;
}
for(i=tot;i>=2;i--) p[p[Q[i]].fail].vis|=p[Q[i]].vis;
for(i=1;i<=tot;i++)
{
if(p[Q[i]].vis) p[Q[i]].ans=p[Q[i]].dep;
for(j=0;j<4;j++)
if(p[Q[i]].ch[j])
p[p[Q[i]].ch[j]].ans=p[Q[i]].ans;
}
for(i=1;i<=m;i++) printf("%d\n",p[pos[i]].ans);
}
int main()
{
scanf("%d%d%s",&n,&m,str);
int i,j,k,u,t;
tot=1;
for(i=1;i<=m;i++)
{
scanf("%s",w);
k=strlen(w);
u=1;
for(j=0;j<k;j++)
{
if(!p[u].ch[dic(w[j])]) p[u].ch[dic(w[j])]=++tot;
u=p[u].ch[dic(w[j])];
p[u].dep=j+1;
}
p[u].cnt++;
pos[i]=u;
}
build();
search();
return 0;
}

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

  1. BZOJ4327 [JSOI2012] 玄武密码 [AC自动机]

    题目传送门 玄武密码 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. 绘图quartz之阴影

          //设置矩形的阴影  并在后边加一个圆 不带阴影     步骤:     CGContextRef context = UIGraphicsGetCurrentContext();     ...

  2. 十五、C# 使用查询表达式的LINQ

    使用查询表达式的LINQ   本章介绍了一种新的语法,查询表达式.   1.查询表达式概述 2.特点:投射  筛选  排序   Let  分组 3.作为方法调用   标准查询运算符所实现的查询在功能上 ...

  3. 浅析CSS中的haslayout

    作为一名web开发人员,最大的希望不是自己的水平有多高,而是希望浏览器厂家能够统一标准,相信任何一个只要是接触过web程序开发的人员都有那样的感受,就是浏览器之间的兼容性问题总是让我们的工作平添诸多的 ...

  4. PHP中的&传值引用的问题,在foreach循环的结果能帮解释下输出的结果原理是什么?

    PHP中的&传值引用的问题,在foreach循环的结果能帮解释下输出的结果原理是什么? 代码如下: <?php $arr = array('one','two','three'); fo ...

  5. 个人工作记录---工作中遇到的sql查询语句解析

    在工作中写了人生的第一个查询语句,虽然是在原有基础上改的,但仍然学到了不少知识 代码: select distinct m.id, (select z.jianc from model_zuzjg z ...

  6. AJAX编程模板

    AJAX一直以来没怎么接触,主要是做JSON数据在服务器和客户端之间传递的时候,被玩坏了,对它莫名的不可爱,最近心理阴影小了,于是又来看看它....... AJAX即“Asynchronous Jav ...

  7. php基础知识【函数】(2)文件file

    一.路径  1.dirname -- 返回路径中的目录部分      $path = "/etc/passwd";      $file = dirname($path); // ...

  8. Javascript 注意点

    prototype有助于减少function的冲突. 闭包有助于避免全部变量. this, prototype有助于实例化多个对象. 函数 函数表达式

  9. Browsing History

    hdu4464:http://acm.hdu.edu.cn/showproblem.php?pid=4464 题意:就是统计n个字符串中每个字符串每个字符对印的Asci,然后输出最大的长度. 题解:水 ...

  10. cf D. Physical Education and Buns

    http://codeforces.com/contest/394/problem/D 题意:给你n个数,然后通过操作使得这n个数变为一个等差数列,操作是可以经过小于等于k次加1或减去1,要使得k尽量 ...