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

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. JDBC基础原理

    一.DCL(了解) -- 1. 创建用户CREATE USER 'zhangsan'@'%' IDENTIFIED BY 'zhangsan';-- 2. 用户授权GRANT ALL ON heima ...

  2. oracle merge 目标表以及源表存在重复列的问题(转)

    SQL> select * from t_source;                                                                      ...

  3. Vue中如何将数据传递到下一个页面(超级简单哒)

    先展示效果:注意URL中值是有变化的 一:在goodslist.vue文件夹绑定 <router-link :to="'/goodsinfo/'+subitem.artID" ...

  4. The new week-学习Python-数据类型

    记录自学Python心得 之前有一段时间的JAVA自学,但最终以“无目标”的状态下被懒散驱散了动力,此为前提 Python的历程就不细细说道了,蛮有趣的 一般大家都是学习的CPython,速度较快(这 ...

  5. 常见的HTTP状态码说明

    1.说明 HTTP服务器状态代码定义(Status Code Definitions) 做测试的时候,会产生比较多的HTTP错误,查看其错误,有超时的,链接不到图片的,连接不到服务器等等,很多人经常忘 ...

  6. C# Mutex互斥锁

    Mutex 构造函数 (Boolean, String, Boolean) public Mutex ( bool initiallyOwned, string name, out bool crea ...

  7. C#、VSTO讀取Excel類

    之前寫的類存在Excel進程不能結束的Bug,重寫ExcelReader類,類實例清理時Excel進程自動結束. class ExcelReader { // Excel Object public ...

  8. readonly与const的区别

    readonly 关键字与 const 关键字不同.const 字段只能在该字段的声明中初始化.readonly字段可以在声明或构造函数中初始化.因此,根据所使用的构造函数,readonly字段可能具 ...

  9. vue-cli3脚手架的配置以及使用

    Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,提供: 通过 @vue/cli 搭建交互式的项目脚手架. 通过 @vue/cli + @vue/cli-service-global  ...

  10. Redis、Memcache区别

    Redis.Memcache区别 redis单核 memcahce多核 redis支持数据持久化 redis支持的数据类型比较多 memcache 只有key->value类型 key-> ...