玄武密码

给若干模式串和一个文本串.求每个模式串在文本串上能匹配的最大前缀长度.

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的更多相关文章

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

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

  2. 4327: JSOI2012 玄武密码

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

  3. 4327: JSOI2012 玄武密码[SAM]

    4327: JSOI2012 玄武密码 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 263  Solved: 112[Submit][Status] ...

  4. P5231 [JSOI2012]玄武密码

    P5231 [JSOI2012]玄武密码 链接 分析: 首先对所有询问串建立AC自动机,然后扫描一遍母串,在AC自动机上走,没走到一个点,标记这个点走过了,并且它的fail树上的祖先节点也可以访问到( ...

  5. HDU2222 Keywords Search 【AC自动机】

    HDU2222 Keywords Search Problem Description In the modern time, Search engine came into the life of ...

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

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

  7. AC自动机讲解+[HDU2222]:Keywords Search(AC自动机)

    首先,有这样一道题: 给你一个单词W和一个文章T,问W在T中出现了几次(原题见POJ3461). OK,so easy~ HASH or KMP 轻松解决. 那么还有一道例题: 给定n个长度不超过50 ...

  8. hdu2222 Keywords Search ac自动机

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=2222 题目: Keywords Search Time Limit: 2000/1000 MS ...

  9. HDU2222 Keywords Search [AC自动机模板]

    Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

随机推荐

  1. mysql 查询的所有操作

    数据查询语言DQL 基本查询语法形式 select [all | distinct] 字段或表达式列表 [from子句] [where子句] [group by子句] [having子句] [orde ...

  2. Linux 线程实现机制分析(转载)

    自从多线程编程的概念出现在 Linux 中以来,Linux 多线应用的发展总是与两个问题脱不开干系:兼容性.效率.本文从线程模型入手,通过分析目前 Linux 平台上最流行的 LinuxThreads ...

  3. Recurrent neural network (RNN) - Pytorch版

    import torch import torch.nn as nn import torchvision import torchvision.transforms as transforms # ...

  4. nginx配置的记录

    基本使用 语法规则: location [=|~|~*|^~] /uri/ { - } = 开头表示精确匹配 ^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可.nginx不对url ...

  5. golang之格式化fmt.Printf

    当使用fmt包打印一个数值时,我们可以用%d.%o或%x参数控制输出的进制格式,就像下面的例子: o := 0666 fmt.Printf("%d %[1]o %#[1]o\n", ...

  6. PAT甲级题分类汇编——线性

    本文为PAT甲级分类汇编系列文章. 线性类,指线性时间复杂度可以完成的题.在1051到1100中,有7道: 题号 标题 分数 大意 时间 1054 The Dominant Color 20 寻找出现 ...

  7. Ubuntu中更改默认的root用户密码,以及怎样修改用户密码

    新安装的Ubuntu系统中默认的root用户密码是多少?该怎么修改? 如题,相信许多刚接触Ubuntu系统的新手大多会遇到这个问题,那么我们该如何解决这个问题呢?Ubuntu在安装过程中并没有让我们设 ...

  8. idea的项目结构

    idea项目结构: 一般是创建一个empty project,然后再创建一个个的Module.

  9. v8 引擎的内存

    一.nodejs查看内容使用情况: process.memoryUsage() 单位为 Btye 转化函数: var format = function(bytes) { return (bytes/ ...

  10. 淘宝图片指纹匹配功能c#实现

    #region 生成图片及图片比较 public String GetHash(Image SourceImg) { Image image = ReduceSize(SourceImg); Byte ...