[AC自动机]玄武密码
题目描述
一个长度为\(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自动机]玄武密码的更多相关文章
- 【BZOJ4327】JSOI2012 玄武密码 AC自动机
[BZOJ4327]JSOI2012 玄武密码 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香 ...
- BZOJ4327 [JSOI2012] 玄武密码 [AC自动机]
题目传送门 玄武密码 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老人们说,这是玄武神 ...
- BZOJ-4327:JSOI2012 玄武密码(AC自动机模板题)
在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老人们说,这是玄武神灵将天书藏匿在此. 很多年后,人们终于在进香 ...
- [BZOJ4327]:[JZOI2012]玄武密码(AC自动机)
题目传送门 题目描述: 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老人们说,这是玄武神灵将天书藏匿在此. ...
- Vijos P1951 玄武密码 (AC自动机)
描述 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老人们说,这是玄武神灵将天书藏匿在此. 很多年后,人们终于在 ...
- 【AC自动机】玄武密码
[题目链接] https://loj.ac/problem/10058 [题意] 对于每一段文字,其前缀在母串上的最大匹配长度是多少呢 [参考别人的题解] https://www.luogu.org/ ...
- TZOJ 5986 玄武密码(AC自动机)
描述 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老人们说,这是玄武神灵将天书藏匿在此. 很多年后,人们终于在 ...
- 2021.11.10 P5231 [JSOI2012]玄武密码(AC自动机)
2021.11.10 P5231 [JSOI2012]玄武密码(AC自动机) https://www.luogu.com.cn/problem/P5231 题意: 给出字符串S和若干T,求S与每个T的 ...
- BZOJ4327 JSOI2012玄武密码(AC自动机)
当然可以在SA上二分答案,但看起来会被卡log.考虑对模板串建出AC自动机,用母串在上面跑,标记上所有能到达的点.注意到达某个点时需要标记所有其通过fail指针可以走到的点,如果遇到一个标记过的点就可 ...
随机推荐
- vue学习(五)生命周期 的钩子函数
生命周期的钩子函数 主要有以下几种 beforeCreate created beforeMount mounted beforeUpdate updated activated deactivate ...
- Linux命令笔记一
#查看文件大小[root@elegant-codes-3 py]# ls -lh total 1.1M -rw-r--r-- 1 root root 5.0K Feb 21 08:18 Crawl_W ...
- pythpon--类操作
#coding=utf-8import numpy as npimport tensorflow as tfimport osos.environ["CUDA_VISIBLE_DEVICES ...
- Java算法练习——正则表达式匹配
题目链接 题目描述 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配. '.' 匹配任意单个字符 '*' 匹配零个或多个前面的那一个元素 所谓匹配,是要 ...
- Oracle:文字与字符串不匹配
执行方法的时候,方法在本地跑是正常,到测试环境报错,错误代码为 ADD_MONTHS(to_date(nvl(T2.EXEC_TIME,t1.DISTRIBUTE_TIME+1),'yyyy-mm-d ...
- invisble
不可见索引概念: 不可见索引(Invisible Index)是ORACLE 11g引入的新特性.不可见索引是会被优化器忽略的不可见索引,除非在会话或系统级别上将OPTIMIZER_USE_INVIS ...
- UML概念
UML UML:Unified Modeling Language是非专利的第三代建模和规约语言.UML是一种开放的方法,用于说明,可视化,结构和编写一个正在开发的,面向对象的,软件密集系统的制品开放 ...
- 2020PHP面试-网络篇
一.网络协议分层 OSI七层: 物理层.数据链路层.网络层.传输层.会话层.表示层.应用层. TCP/IP四(五)层 : 物理层(主要是光电信号的传输). 数据链路层(MAC地址.以太网协议).网络层 ...
- LVM中逻辑卷的最大大小限制
前言: 本文是对这篇博客Maximum Size Of A Logical Volume In LVM的翻译,敬请尊重原创和翻译劳动成果,那些随意转载的大爷们,好歹也自觉注明出处.谢谢! 英文原文地址 ...
- jdk 的安装教程
1. 配置的位置 鼠标右击计算机----属性-----高级系统设置---环境变量----在系统变量中配置(推荐) 2.增加环境变量 (1)新建 ----- 变量名: JAVA_HOME 变量值 ...