题目思路没话讲;主要是做题时候的细节和经验

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。


题目分析

题目的做法很显然:标记一下哪些节点被匹配过,之后再dfs找被匹配过的最大深度。

这里记录一下做题经验:

  1. 字符集能压缩的尽量压缩(和离散化一个道理),trie毕竟还有|S|的常数在这里。
  2. 查询跳匹配的时候for (int v=u; v&&!vis[v]; v=nxt[v])的!vis[v]这个优化非常重要

以上。

 #include<bits/stdc++.h>
const int maxNode = ;
const int maxn = ; char s[maxn],t[];
int n,m,c[],l[],cnt;
struct ACAutomaton
{
bool vis[maxNode];
std::queue<int> q;
int nxt[maxNode],f[maxNode][],fa[maxNode],tot; inline int get(char ch)
{
if(ch=='W') return ;
if(ch=='E') return ;
if(ch=='S') return ;
return ;
}
void insert(char *s)
{
int u = , lens = strlen(s);
for (int i=; i<lens; i++)
{
int c = get(s[i]);
if (!f[u][c]) f[u][c] = ++tot, fa[f[u][c]] = u;
u = f[u][c];
}
c[++cnt] = u;
}
void build()
{
for (int i=; i<; i++) f[][i] = ;
q.push();
while (q.size())
{
int tt = q.front();
q.pop();
for (int i=; i<; i++)
if (f[tt][i])
nxt[f[tt][i]] = f[nxt[tt]][i], q.push(f[tt][i]);
else f[tt][i] = f[nxt[tt]][i];
}
}
int query(int s, int t)
{
for (; s; s=fa[s], t--)
if (vis[s]) return t;
return ;
}
void match(char *s)
{
int u = , lens = strlen(s);
for (int i=; i<lens; i++)
{
int c = get(s[i]);
u = f[u][c];
for (int v=u; v&&!vis[v]; v=nxt[v]) vis[v] = ;
}
}
}f; int main()
{
scanf("%d%d%s",&n,&m,s);
f.tot = ;
for (int i=; i<=m; i++)
{
scanf("%s",t);
f.insert(t);
l[i] = strlen(t);
}
f.build(), f.match(s);
for (int i=; i<=m; i++)
printf("%d\n",f.query(c[i], l[i]));
return ;
}

END

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

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

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

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

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

  3. BZOJ4327 : JSOI2012 玄武密码

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

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

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

  5. 【文文殿下】[BZOJ4327] JSOI2012 玄武密码

    SAM裸题.这道题卡空间.要小心数组别开炸了. #include<cstdio> #include<cstring> typedef long long ll; const i ...

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

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

  7. 2021.11.10 P5231 [JSOI2012]玄武密码(AC自动机)

    2021.11.10 P5231 [JSOI2012]玄武密码(AC自动机) https://www.luogu.com.cn/problem/P5231 题意: 给出字符串S和若干T,求S与每个T的 ...

  8. 4327: JSOI2012 玄武密码

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

  9. P5231 [JSOI2012]玄武密码

    P5231 [JSOI2012]玄武密码 链接 分析: 首先对所有询问串建立AC自动机,然后扫描一遍母串,在AC自动机上走,没走到一个点,标记这个点走过了,并且它的fail树上的祖先节点也可以访问到( ...

随机推荐

  1. 洛谷P4568 飞行路线

    题目描述 \(Alice\)和\(Bob\)现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在\(n\)个城市设有业务,设这些城市分别标记为\(0\)到\(n−1\),一共有\(m\ ...

  2. PAT甲级——1103 Integer Factorization (DFS)

    本文同步发布在CSDN:https://blog.csdn.net/weixin_44385565/article/details/90574720 1103 Integer Factorizatio ...

  3. VUE图片懒加载-vue lazyload插件的简单上手使用(优化版本)

    在用VUE做项目开发的过程中,首页用到了懒加载的方法,查找了一些方法,觉得官网写得太复杂,有一篇博客不错(https://www.cnblogs.com/xyyt/p/7650539.html),但是 ...

  4. STM32开关总中断

    引用 http://www.amobbs.com/forum.php?mod=viewthread&tid=5397451 在 STM32/Cortex-M3 中是通过改变 CPU 的当前优先 ...

  5. MapReduce作业的执行流程

    MapReduce任务执行总流程 一个MapReduce作业的执行流程是:代码编写 -> 作业配置 -> 作业提交 -> Map任务的分配和执行 -> 处理中间结果 -> ...

  6. 4. 把一幅彩色图像的R、G、B分量单独显示。

    #include <cv.h> #include <highgui.h> int main(void) { IplImage* oo = cvLoadImage(); IplI ...

  7. JS中实现JSON对象和JSON字符串之间的相互转换

    对于主流的浏览器(比如:firefox,chrome,opera,safari,ie8+),浏览器自己提供了JSON对象,其中的parse和stringify方法实现了JSON对象和JSON字符串之间 ...

  8. VS2012,更新补丁后的残忍--创建项目未找到与约束匹配的导出

    解决方法网址:http://blog.csdn.net/jly4758/article/details/18660945

  9. webpack.config.js====output出口文件的配置

    output: { filename: './js/[name].[hash:8].js', /* * filename:在使用webpack-dev-server模式时,如果要使用hash,是不可以 ...

  10. 利用mysqldump备份magento数据库

    在Magento开发和维护过程中,经常需要将Magento的数据库导出.导入,这些工作可以通过mysqldump这个工具来实现. 下面我来简单介绍一下mysqldump在导出导入Magento dat ...