JSOI2012 玄武密码 和 HDU2222 Keywords Search
玄武密码
给若干模式串和一个文本串.求每个模式串在文本串上能匹配的最大前缀长度.
N<=107,M<=105,每一段文字的长度<=100。
jklover的题解
将模式串建成一个 AC 自动机,匹配文本串的时候往前暴力跳,跳到第一个合法的位置即可.
时间复杂度:线性。
co int N=1e7+1,S=4;
int n,m;
int len[N];
namespace AC
{
int idx;
int id(char x)
{
switch(x)
{
case 'E':
return 0;
case 'W':
return 1;
case 'N':
return 2;
case 'S':
return 3;
default:
assert(0);
}
}
int ch[N][S],fa[N],fail[N];
int marked[N],val[N];
void ins(char s[],int v)
{
int u=0;
for(int i=0;i<len[v];++i)
{
int k=id(s[i]);
if(!ch[u][k])
{
fa[++idx]=u;
ch[u][k]=idx;
}
u=ch[u][k];
}
val[v]=u;
}
void getfail()
{
std::queue<int>Q;
for(int i=0;i<S;++i)
if(ch[0][i])
Q.push(ch[0][i]);
while(Q.size())
{
int u=Q.front();Q.pop();
for(int i=0;i<S;++i)
{
if(ch[u][i])
{
fail[ch[u][i]]=ch[fail[u]][i];
Q.push(ch[u][i]);
}
else
ch[u][i]=ch[fail[u]][i];
}
}
}
void mark(char*s)
{
int u=0;
for(int i=0;i<n;++i)
{
int k=id(s[i]);
u=ch[u][k];
for(int j=u;j&&!marked[j];j=fail[j])
marked[j]=1;
}
}
int work(int x)
{
int ans=len[x];
for(int i=val[x];i;i=fa[i],--ans)
if(marked[i])
return ans;
}
}
char buf[110];
char s[N];
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
read(n),read(m);
scanf("%s",s);
for(int i=1;i<=m;++i)
{
scanf("%s",buf);
len[i]=strlen(buf);
AC::ins(buf,i);
}
AC::getfail();
AC::mark(s);
for(int i=1;i<=m;++i)
{
int ans=AC::work(i);
printf("%d\n",ans);
}
return 0;
}
Keywords Search
给若干个模式串,再给一个文本串,问有几个模式串在文本串中出现过.
jklover的题解
板子题.注意一个模式串只被计算一次,统计后做上标记.
这里采用的是补全 Trie 树的写法.
时间复杂度线性。主要是找出现的这里:
for(int j=u;j&&val[j]!=-1;j=fail[j])
res+=val[j],val[j]=-1;
但这里每个节点最多访问一次,也是线性的。
可以用蓝书上的last代替。
代码
HDU不给用<bits/stdc++.h>……
co int N=5e5+1,S=26;
namespace AC
{
int idx;
int ch[N][S],fail[N],val[N];
void init()
{
idx=0;
memset(val,0,sizeof val);
memset(ch,0,sizeof ch);
memset(fail,0,sizeof fail);
}
void ins(char s[],int n)
{
int u=0;
for(int i=0;i<n;++i)
{
int k=s[i]-'a';
if(!ch[u][k])
ch[u][k]=++idx;
u=ch[u][k];
}
++val[u];
}
void getfail()
{
std::queue<int>Q;
for(int i=0;i<S;++i)
if(ch[0][i])
Q.push(ch[0][i]);
while(Q.size())
{
int u=Q.front();Q.pop();
for(int i=0;i<S;++i)
{
if(ch[u][i])
{
fail[ch[u][i]]=ch[fail[u]][i];
Q.push(ch[u][i]);
}
else
ch[u][i]=ch[fail[u]][i];
}
}
}
int query(char s[],int n)
{
int u=0,res=0;
for(int i=0;i<n;++i)
{
int k=s[i]-'a';
u=ch[u][k];
for(int j=u;j&&val[j]!=-1;j=fail[j])
res+=val[j],val[j]=-1;
}
return res;
}
}
char buf[N*2];
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
int t;
read(t);
while(t--)
{
AC::init();
int n;
read(n);
for(int i=1;i<=n;++i)
{
scanf("%s",buf);
AC::ins(buf,strlen(buf));
}
AC::getfail();
scanf("%s",buf);
int ans=AC::query(buf,strlen(buf));
printf("%d\n",ans);
}
return 0;
}
JSOI2012 玄武密码 和 HDU2222 Keywords Search的更多相关文章
- 【BZOJ4327】JSOI2012 玄武密码 AC自动机
[BZOJ4327]JSOI2012 玄武密码 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香 ...
- 4327: JSOI2012 玄武密码
4327: JSOI2012 玄武密码 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中.老 ...
- 4327: JSOI2012 玄武密码[SAM]
4327: JSOI2012 玄武密码 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 263 Solved: 112[Submit][Status] ...
- P5231 [JSOI2012]玄武密码
P5231 [JSOI2012]玄武密码 链接 分析: 首先对所有询问串建立AC自动机,然后扫描一遍母串,在AC自动机上走,没走到一个点,标记这个点走过了,并且它的fail树上的祖先节点也可以访问到( ...
- HDU2222 Keywords Search 【AC自动机】
HDU2222 Keywords Search Problem Description In the modern time, Search engine came into the life of ...
- 2021.11.10 P5231 [JSOI2012]玄武密码(AC自动机)
2021.11.10 P5231 [JSOI2012]玄武密码(AC自动机) https://www.luogu.com.cn/problem/P5231 题意: 给出字符串S和若干T,求S与每个T的 ...
- AC自动机讲解+[HDU2222]:Keywords Search(AC自动机)
首先,有这样一道题: 给你一个单词W和一个文章T,问W在T中出现了几次(原题见POJ3461). OK,so easy~ HASH or KMP 轻松解决. 那么还有一道例题: 给定n个长度不超过50 ...
- hdu2222 Keywords Search ac自动机
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=2222 题目: Keywords Search Time Limit: 2000/1000 MS ...
- HDU2222 Keywords Search [AC自动机模板]
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
随机推荐
- 微信小程序中的事件绑定
前言: 微信小程序中的事件绑定和Vue中的事件绑定其实有很多的相似之处,所以如果有过Vue相关的经验,学起来的话还是比较容易的. js代码: // 页面级的js文件必须调用Page函数来注册页面, / ...
- mysql You can't specify target table for update in FROM clause解决方法
mysql You can't specify target table for update in FROM clause解决方法出现这个错误的原因是不能在同一个sql语句中,先select同一个表 ...
- noVNC使用——访问多台vnc
一.模拟实验环境 1.CentOS6.8系统2.KVM环境3.使用KVM环境的两个系统(Windows,Linux)4.noVNC5.vncserver 二.实验过程1.在kvm的环境下,通过xml创 ...
- Djang简单使用
用户访问内容 用户能够访问的所有的资源,都是程序猿提前暴露的,如果没有暴露,用户是不能进行访问的. diango重启的问题 当我们更改django中的代码的时候,django内部会检测到我们更 ...
- [转帖]CentOS 7 安装 GlusterFS
CentOS 7 安装 GlusterFS https://www.cnblogs.com/jicki/p/5801712.html 改天测试一下 我一直没有搞这一块呢. CentOS 7 Glu ...
- smarty中常用的流程控制逻辑
if else {if $age > 18} <div>年满十八岁!</div> {else if $age > 16} <div>年满十六岁!< ...
- FFmpeg开发教程一、FFmpeg 版 Hello world
本系列根据项目ffmpeg-libav-tutorial翻译而来 Chapter 0 - 万物之源 -- hello world 然而,本节的程序并不会在终端打印"Hello world&q ...
- Quartz入门以及相关表达式使用
目的: 1.Quartz简介及应用场景 2.Quartz简单触发器 SimpleTrigger介绍 3.Quartz表达式触发器CronTirgger介绍 4.Quartz中参数传递 5.Spring ...
- idea的项目结构
idea项目结构: 一般是创建一个empty project,然后再创建一个个的Module.
- idea代码提示快捷键设置
代码提示快捷键设置: keymap--Main Menu--Code--Completion--Basic