玄武密码

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

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. 查看cpu核的相关信息

    查看CPU信息(型号) cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c 80 Intel(R) Xeon(R) CPU E7-4820 v3 ...

  2. python format函数/print 函数详细讲解(4)

    在python开发过程中,print函数和format函数使用场景特别多,下面分别详细讲解两个函数的用法. 一.print函数 print翻译为中文指打印,在python中能直接输出到控制台,我们可以 ...

  3. Python3实现自动查询成绩(主要使用的包有Tesseract-OCR、PIL、execjs、pytesseract、BeautifulSoup)

    前提:本文仅作为技术训练,不可利用技术做非法的事. 某考试的成绩查询页面如下:查询成绩需要的数据有准考证号或者身份证.考生姓名.验证码.现在使用python来实现自动查询指定人员的考试成绩(不知道准考 ...

  4. DateTimeFormatter 的操作与使用 -- 通俗易懂

    在上一章我们讲解了LocalDate.LocalTime.LocalDateTime.Instant的操作与使用,下面讲解它们之间是如何进行格式化 DateTimeFormatter这个类它只提供了时 ...

  5. csdn博客整理

    @TOC 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页.如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown ...

  6. go http简单的表单处理

    //表单处理 package main import (     "net/http"     "io"     "fmt"     &qu ...

  7. oracle sqlplus命令

    show和set命令是两条用于维护SQL*Plus系统变量的命令 SQL> show all --查看所有68个系统变量值 SQL> show user --显示当前连接用户 SQL> ...

  8. maven配置阿里镜像

    在conf\settings.xml 在<mirrors>里面添加   <mirror>    <id>nexus-aliyun</id>    < ...

  9. DNS 解析

    DNS即为Domain Name System的缩写形式,就是所谓的域名系统,它是互联网的一项服务.它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网. 如果想访问某个网站( ...

  10. Rubost PCA 优化

    Rubost PCA 优化 2017-09-03 13:08:08 YongqiangGao 阅读数 2284更多 分类专栏: 背景建模   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA ...