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

描述

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

很多年后,人们终于在进香河地区发现了带有玄武密码的文字。更加神奇的是,这份带有玄武密码的文字,与玄武湖南岸台城的结构有微妙的关联。于是,漫长的破译工作开始了。

经过分析,我们可以用东南西北四个方向来描述台城城砖的摆放,不妨用一个长度为N的序列来描述,序列中的元素分别是‘E’,‘S’,‘W’,‘N’,代表了东南西北四向,我们称之为母串。而神秘的玄武密码是由四象的图案描述而成的M段文字。这里的四象,分别是东之青龙,西之白虎,南之朱雀,北之玄武,对东南西北四向相对应。

现在,考古工作者遇到了一个难题。对于每一段文字,其前缀在母串上的最大匹配长度是多少呢?

输入

第一行有两个整数,N和M,分别表示母串的长度和文字段的个数。

第二行是一个长度为N的字符串,所有字符都满足是E,S,W和N中的一个。

之后M行,每行有一个字符串,描述了一段带有玄武密码的文字。依然满足,所有字符都满足是E,S,W和N中的一个。

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

输出

输出有M行,对应M段文字。

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

样例输入

7 3
SNNSSNS
NNSS
NNN
WSEE

样例输出

4
2
0

题意

如上。

题解

M个串建AC自动机,由于只有ESWN四个字符,所以只用开4,记录串i在AC自动机最后的位置id,并且记录父节点father和深度d。

查询S所能到达的所有节点,标记vis。

最后串i最后的位置id(叶子节点)往上跑,如果已经被标记输出dis。

时间复杂度O(N+100*M)。

代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3
 4 const int N=1e7+5,M=1e5+5;
 5 int tot,son[N][4],father[N],fail[N],q[N],d[N],id[M];
 6 int n,m;char s[N],s1[N];
 7 bool vis[N];
 8 inline int get(char ch){
 9     if(ch==‘E‘)return 0;
10     else if(ch==‘S‘)return 1;
11     else if(ch==‘W‘)return 2;
12     else return 3;
13 }
14 void insert(int p){
15     for(int l=strlen(s),x=0,i=0,w;i<l;i++){
16         if(!son[x][w=get(s[i])])son[x][w]=++tot;
17         father[son[x][w]]=x;d[son[x][w]]=d[x]+1;x=son[x][w];
18         if(i==l-1)id[p]=x;
19     }
20 }
21 void make(){
22     int h=1,t=0,i,j,x;fail[0]=-1;
23     for(i=0;i<4;i++)if(son[0][i])q[++t]=son[0][i];
24     while(h<=t)for(x=q[h++],i=0;i<4;i++)
25         if(son[x][i])fail[son[x][i]]=son[fail[x]][i],q[++t]=son[x][i];
26         else son[x][i]=son[fail[x]][i];
27 }
28 void find(){
29     for(int l=n,x=0,i=0,j;i<l;i++){
30         x=son[x][get(s1[i])];
31         for(j=x;j;j=fail[j])vis[j]=1;
32     }
33 }
34 int dfs(int u){
35     for(int i=u;i>0;i=father[i])
36         if(d[i]&&vis[i])return d[i];
37     return 0;
38 }
39 int main()
40 {
41     scanf("%d%d%s",&n,&m,s1);
42     for(int i=1;i<=m;i++)scanf("%s",s),insert(i);
43     make();
44     find();
45     for(int i=1;i<=m;i++)printf("%d\n",dfs(id[i]));
46     return 0;
47 }

原文地址:https://www.cnblogs.com/taozi1115402474/p/11421493.html

时间: 2024-08-27 05:07:06

TZOJ 5986 玄武密码(AC自动机)的相关文章

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

题目描述 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老人们说,这是玄武神灵将天书藏匿在此. 很多年后,人们终于在进香河地区发现了带有玄武密码的文字.更加神奇的是,这份带有玄武密码的文字,与玄武湖南岸台城的结构有微妙的关联.于是,漫长的破译工作开始了. 经过分析,我们可以用东南西北四个方向来描述台城城砖的摆放,不妨用一个长度为N的序列来描述,序列中的元素分别是‘E’,‘S’,‘W’,‘N’,代表了东南西北四

[BZOJ1559]密码 AC自动机+状压

问题 K: [JSOI2009]密码 时间限制: 1 Sec  内存限制: 64 MB 题目描述 众所周知,密码在信息领域起到了不可估量的作用.对于普通的登陆口令,唯一的破解 方法就是暴力破解一逐个尝试所有可能的字母组合,但这是一项很耗时又容易被发现的工 作.所以,为了获取对方的登陆口令,在暴力破解密码之前,必须先做大量的准备工作.经 过情报的搜集,现在得到了若干有用信息,形如: “我观察到,密码中含有字符串***.” 例如,对于一个10位的密码以及观察到的字符串hello与world,可能的密

BZOJ 1559: [JSOI2009]密码( AC自动机 + 状压dp )

建AC自动机后, dp(x, y, s)表示当前长度为x, 在结点y, 包括的串的状态为s的方案数, 转移就在自动机上走就行了. 对于输出方案, 必定是由给出的串组成(因为<=42), 所以直接暴搜答案. 数据范围很小, 可以AC(复杂度懒得算了....) ------------------------------------------------------------------------------------------------ #include<cstdio> #in

[BZOJ1559][JSOI2009]密码(AC自动机)

http://www.lydsy.com/JudgeOnline/problem.php?id=1559 2009年的省选题虽然比起现在简单了不少,但对我来说还是很有挑战性的. 首先对于这种多串匹配问题,第一个想到的就应该是AC自动机. 还是老套路,f[i][j]表示走到字符串的第i位,现在在自动机上的第j位时的信息.增加一维n位的压位表示各个串是否都被匹配到了. 但是这里有个问题,如果S1包含了S2,那么我们只需要S1被匹配就能保证S2也被匹配,而不需要在自动机上走到S2的位置. 这样我们预处

AC自动机 --- [JSOI2012]玄武密码

bzoj 4327 [JSOI2012]玄武密码 题目描述 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河. 相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老人们说,这是玄武神灵将天书藏匿在此. 很多年后,人们终于在进香河地区发现了带有玄武密码的文字. 更加神奇的是,这份带有玄武密码的文字,与玄武湖南岸台城的结构有微妙的关联.于是,漫长的破译工作开始了. 经过分析,我们可以用东南西北四个方向来描述台城城砖的摆放,不妨用一个长度为N的序列来描述,序列中的元素

【AC自动机】玄武密码

[题目链接] https://loj.ac/problem/10058 [题意] 对于每一段文字,其前缀在母串上的最大匹配长度是多少呢 [参考别人的题解] https://www.luogu.org/problemnew/solution/P5231 我们只需要先建立所有密码的trie树再以母串为主串跑一个AC自动机不过其中还是有一些需要改动的地方原本字典树中用来记录某个节点是不是字符串结尾的数组不需要,直接删去我们需要另一个数组来标记哪些点被匹配跑完ac自动机后从trie树上找最后一个匹配的点

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

题目思路没话讲:主要是做题时候的细节和经验 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老人们说,这是玄武神灵将天书藏匿在此. 很多年后,人们终于在进香河地区发现了带有玄武密码的文字.更加神奇的是,这份带有玄武密码的文字,与玄武湖南岸台城的结构有微妙的关联.于是,漫长的破译工作开始了. 经过分析,我们可以用东南西北四个方向来描述台城城砖的摆放,不妨用一个长度为N的序列来描述,序列中的

[AC自动机]玄武密码

题目描述 一个长度为\(N\)的母串,有四个元素分别是:N,S,W,N. 有M个长度为100的模式串. 现在要求每个模式串的前缀与母串匹配最长长度. 输入样例 7 3 SNNSSNS NNSS NNN WSEE 输出样例 4 2 0 题解 这是AC自动机的模板题 关键是判断模式串的前缀是否被匹配 因为AC自动机的一个结点代表一个前缀,通过fail指针的遍历可以标记所有匹配的前缀 首先将模式串插入到trie树中,构造自动机 再将母串输入到AC自动机中,把匹配到的前缀即结点都标记一下.这里有一个剪枝

AC自动机 &amp; fail树

[BZOJ 1195] 最短母串 题意 给定 n (n <= 12) 个子串 s (|s| <= 60) , 求一个最短母串. 分析 建 AC 自动机. 设 St 为每个点的状态, 在 fail 树上下传一下. 直接 BFS 找到第一个满的状态 (Node, State) . [BZOJ 4327] [JSOI 2012] 玄武密码 题意 给定一个母串和若干个模式串. 求每个模式串最多能在母串上匹配多少位. |S| <= 10000000, |T| <= 100, m <=