题目描述

一个长度为\(N\)的母串,有四个元素分别是:N,S,W,N.

有M个长度为100的模式串.

现在要求每个模式串的前缀与母串匹配最长长度.

输入样例

7 3

SNNSSNS

NNSS

NNN

WSEE

输出样例

4

2

0

题解

这是AC自动机的模板题

关键是判断模式串的前缀是否被匹配

因为AC自动机的一个结点代表一个前缀,通过fail指针的遍历可以标记所有匹配的前缀

首先将模式串插入到trie树中,构造自动机

再将母串输入到AC自动机中,把匹配到的前缀即结点都标记一下.这里有一个剪枝,如果当前结点已经标记过了,那就可以break了,因为这个结点到根节点一定标记了.

最后再将每个模式串输入到AC自动机中,如果当前结点被标记就更新答案.当前结点被标记说明前缀已匹配.

代码

最开始有个小细节重要东西没注意导致RE

数组开了400,当时理由是100*4

果然是退役久了变傻了,状态肯定不止400,画一个四叉树就知道了,状态数应该选字符串总长比较合适

#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h> using namespace std;
const int N = 110;
const int M = 1e5 + 7;
namespace AC {
int tr[10000000][4], tot;
int fail[10000000];
bool vis[10000000]; inline int id(char ch) {
if (ch == 'E') return 0;
else if (ch == 'S') return 1;
else if (ch == 'W') return 2;
else if (ch == 'N') return 3;
return 0;
} void insert(char *s) {
int u = 0, k = 0;
for (int i = 1; s[i]; ++i) {
k = id(s[i]);
if (!tr[u][k]) tr[u][k] = ++tot;
u = tr[u][k];
}
} queue<int> q; void build() {
for (int i = 0; i < 4; ++i) {
if (tr[0][i]) {
q.push(tr[0][i]);
}
}
while (!q.empty()) {
int u = q.front();
q.pop();
for (int i = 0; i < 4; ++i) {
if (tr[u][i]) {
fail[tr[u][i]] = tr[fail[u]][i];
q.push(tr[u][i]);
} else {
tr[u][i] = tr[fail[u]][i];
}
}
}
} void query(char *t) {
int u = 0;
for (int i = 1; t[i]; ++i) {
u = tr[u][id(t[i])];
for (int j = u; j && vis[j] != 1; j = fail[j]) {
vis[j] = true;
}
}
} int get_ans(char *s) {
int u = 0, res = 0;
for (int i = 1; s[i]; ++i) {
u = tr[u][id(s[i])];
if (vis[u]) res = i;
}
return res;
}
}
char str[M][N];
char p[10000005]; int main() {
int n, m;
scanf("%d %d", &n, &m);
scanf("%s", p + 1);
for (int i = 1; i <= m; ++i) {
scanf("%s", str[i] + 1);
AC::insert(str[i]);
}
AC::build();
AC::query(p);
for (int i = 1; i <= m; ++i) {
printf("%d\n", AC::get_ans(str[i]));
}
return 0;
}

 这个题虽然是以前做过的,但久了就忘了,当时也没有真正理解其精髓

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

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

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

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

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

  3. BZOJ-4327:JSOI2012 玄武密码(AC自动机模板题)

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

  4. [BZOJ4327]:[JZOI2012]玄武密码(AC自动机)

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

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

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

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

    [题目链接] https://loj.ac/problem/10058 [题意] 对于每一段文字,其前缀在母串上的最大匹配长度是多少呢 [参考别人的题解] https://www.luogu.org/ ...

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

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

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

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

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

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

随机推荐

  1. [BJDCTF2020]The mystery of ip

    0x00 知识点 SSTI模板注入: 之前也写过: https://www.cnblogs.com/wangtanzhi/p/12238779.html SSTI模板注入: 模板注入涉及的是服务端We ...

  2. 如何在Ubuntu 18.04上安装和卸载TeamViewer

    卸载命令:sudo apt --purge remove teamviewer 安装:https://www.linuxidc.com/Linux/2018-05/152282.htm 如何在Ubun ...

  3. 【LeetCode】子集

    [问题]给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集).说明:解集不能包含重复的子集. 示例: 输入: nums = [,,] 输出: [ [], [], [], [,,] ...

  4. 网络基础:OSI 七层模型、TCP/IP 四层模型

    1.Internet历史 1. 1968年由美国ARPA机构提出"资源共享计算机网络”,让ARPA的计算机互联起来,叫做阿帕网;2. 1974年,第一个TCP协议详细说明发布了.3. 一个 ...

  5. 文献及代码阅读报告 - SS-LSTM:A Hierarchical LSTM Model for Pedestrian Trajectory Prediction

    概览 简述 SS-LSTM全称Social-Scene-LSTM,是一种分层的LSTM模型,在已有的考虑相邻路人之间影响的Social-LSTM模型之上额外增加考虑了行人背景的因素.SS-LSTM架构 ...

  6. 仿flash的文字动画效果

    .tips{ font-size: 24px; font-family: sans-serif; font-weight: 600; text-shadow: 1px 1px #ffb700; col ...

  7. HDU_2871 线段树+vecor的中间插入和删除使用

    本来这个题目就是个合并区间的题,就跟Hotel一样,要插入一段,则找左孩子 合并后的中间区间 右孩子,但是比较恶心的是,他需要实时得到某一段的起终点,或者某个点在第几个段里面,我想过在线段树里面加入几 ...

  8. 掌握这三点,轻松搞定Essay写作

    英文essay写作涉及的范围很广,任何文字形式的材料都涉及写作.所以,不单单是专业的文字工作者要在写作上下功夫,一般人在从小到大的学校教育里要应对的作文.读书报告.美国高中及大学里的论文.英文演讲以及 ...

  9. linux_c_udp_example

    udp_server #include <stdlib.h> #include <string.h> #include <unistd.h> #include &l ...

  10. JAVA函数库

    1. 文件相关 1.1 判断目录是否存在 public static boolean dictionaryExist(String path) { File file = new File(path) ...