【AC自动机】bzoj4327: JSOI2012 玄武密码
题目思路没话讲;主要是做题时候的细节和经验
Description
Input
Output
Sample Input
SNNSSNS
NNSS
NNN
WSEE
Sample Output
2
0
HINT
对于100%的数据,N<=10^7,M<=10^5,每一段文字的长度<=100。
题目分析
题目的做法很显然:标记一下哪些节点被匹配过,之后再dfs找被匹配过的最大深度。
这里记录一下做题经验:
- 字符集能压缩的尽量压缩(和离散化一个道理),trie毕竟还有|S|的常数在这里。
- 查询跳匹配的时候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 玄武密码的更多相关文章
- BZOJ4327 [JSOI2012] 玄武密码 [AC自动机]
题目传送门 玄武密码 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老人们说,这是玄武神 ...
- BZOJ4327 JSOI2012玄武密码(AC自动机)
当然可以在SA上二分答案,但看起来会被卡log.考虑对模板串建出AC自动机,用母串在上面跑,标记上所有能到达的点.注意到达某个点时需要标记所有其通过fail指针可以走到的点,如果遇到一个标记过的点就可 ...
- BZOJ4327 : JSOI2012 玄武密码
对所有询问串建立AC自动机. 然后将母串在AC自动机上跑,每走到一个点x,从x点出发沿着fail指针能到的所有前缀都是匹配成功的,暴力向上走,碰到走过的就break,这样每个点最多只会被标记一次. 时 ...
- BZOJ4327:[JSOI2012]玄武密码(SAM)
Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老人们说,这是玄武神灵将天书藏匿在此. ...
- 【文文殿下】[BZOJ4327] JSOI2012 玄武密码
SAM裸题.这道题卡空间.要小心数组别开炸了. #include<cstdio> #include<cstring> typedef long long ll; const i ...
- 【BZOJ4327】JSOI2012 玄武密码 AC自动机
[BZOJ4327]JSOI2012 玄武密码 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香 ...
- 2021.11.10 P5231 [JSOI2012]玄武密码(AC自动机)
2021.11.10 P5231 [JSOI2012]玄武密码(AC自动机) https://www.luogu.com.cn/problem/P5231 题意: 给出字符串S和若干T,求S与每个T的 ...
- 4327: JSOI2012 玄武密码
4327: JSOI2012 玄武密码 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老 ...
- P5231 [JSOI2012]玄武密码
P5231 [JSOI2012]玄武密码 链接 分析: 首先对所有询问串建立AC自动机,然后扫描一遍母串,在AC自动机上走,没走到一个点,标记这个点走过了,并且它的fail树上的祖先节点也可以访问到( ...
随机推荐
- vue教程3-webpack搭建项目
vue-cli https://cli.vuejs.org/zh/ vue-cli是vue的命令行工具,对于创建项目,安装各种组件,运行项目都极为方便,是在开发vue中的必备工具 vue-cli基于n ...
- java join 方法的使用
在很多情况下,主线程创建并启动子线程,如果子线程中要进行大量的耗时运算,主线程往往将早于子线程结束之前结束.这时,如果主线程想等待子线程执行完成之后再结束,比如子线程处理一个数据,主线程要取得这个数据 ...
- JsonModel&AFNetWorking
// HttpManager.h // JsonModel&AFNetWorking // // Created by qianfeng on 15/7/21. // Copyright (c ...
- JAVA基础之项目分包
个人理解: 项目分层分包适合多人开发合作的,最好一个界面设置一个view,同时注释一定设置好,按照顺序:从前向后进行传递参数,从后向前进行传递返回值来进行判断是否真正的执行了sql语句(可以不返回), ...
- Spring注入属性、对象
对Category和Product注入属性,并且对Product对象,注入一个Category对象 一.新建项目 二.导包 三.新建Category类 package com.yyt.pojo; pu ...
- Mysql中WHERE IN,UNION 用法详解
WHERE IN 用法 这里分两种情况来介绍 1.in 后面是记录集,如: select * from table where uname in(select uname from ...
- Kendo MVVM 数据绑定(八) Style
Kendo MVVM 数据绑定(八) Style Style 绑定可以通过 ViewModel 绑定到 DOM 元素 CSS 风格属性,例如: <span data-bind="sty ...
- Collection-Iterator-foreach
一.Collection(java.util) 1.概述:具有相同性质的一类事物的汇聚的整体,称为集合.任何集合都包含三块内容:对外的接口/接口的实现/对集合运算的算法. java中使 ...
- MySQL查询示例
use test; create table t1(tid smallint(5) unsigned auto_increment,tname varchar(50),tkecheng varchar ...
- vue搭建骨架屏步骤配置
1.什么是骨架屏幕? 在页面加载数据之前,有一段空白时间,要么用loading加载,要么就用骨架屏. 在开发webapp的时候总是会受到首屏加载时间过长的影响,主流的解决方法是在载入完成之前显示loa ...