【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树上的祖先节点也可以访问到( ...
随机推荐
- react-native-contact 安卓已测试,
1. 下载模块 npm install react-native-contacts --save 2.安卓配置: a.在android/settings.gradle include ':rea ...
- POJ1830(异或高斯消元)
对于某个开关,都有n个选项可能影响它的结果,如果会影响,则系数为1,否则系数为0:最后得到自由元的个数,自由元可选0也可选1. #include <cstdio> #include < ...
- CodeForces - 508B-Anton and currency you all know
Berland, 2016. The exchange rate of currency you all know against the burle has increased so much th ...
- Uvalive-4494-(数位dp)
题意:求a->b中的二进制出现过多少个1,很显然的数位dp,对于某一位来说,如果这位是0,那么dp[i]=dp[i-1] 如果这一位是1 那么dp[i]=dp[i-1]+1<<(p ...
- poj1185-炮兵阵地(状态压缩dp)
炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 25647 Accepted: 9892 Description ...
- byte取高4位,低4位,byte转int
byte abyte =-1; System.out.println(abyte); System.out.println(Integer.toBinaryString(abyte)); //取高四位 ...
- NET Core 2.0使用Cookie认证实现SSO单点登录
NET Core 2.0使用Cookie认证实现SSO单点登录 之前写了一个使用ASP.NET MVC实现SSO登录的Demo,https://github.com/bidianqing/SSO.Sa ...
- Jaspersoft Studio简介
参考来源:https://community.jaspersoft.com/documentation/tibco-jaspersoft-studio-user-guide/v640/introduc ...
- git 本地新建分支Push到远程
1. 本地新建分支,并切换到新的分支 git branch local_branch; git checkout local_branch; 2.第一条的命令也可以简单的一条命令来替代 git che ...
- 《从0到1学习Flink》—— 如何自定义 Data Source ?
前言 在 <从0到1学习Flink>-- Data Source 介绍 文章中,我给大家介绍了 Flink Data Source 以及简短的介绍了一下自定义 Data Source,这篇 ...