题意

给出n个模式串和一个文本串,输出各个模式串在文本串中出现的次数。模式串有两种类型,0类型代表可以有重叠,1类型代表不能有重叠。模式串可能出现重复。

分析

算是AC自动机的模板题?

因为模式串可以重复,所以如果直接插入并且用val数组来保存模式串的编号的话,后面出现的会把前面出现的给覆盖。所以我这里用了一个map来保存每个模式串在trie中的编号。

如何处理1类型不能有重叠的情况?对于1类型的每个模式串,记录一下它的长度和上次匹配到的位置。当再次匹配到这个模式串的时候,看一下这次的位置和上次位置的差有没有大于它的长度,如果大于,则说明这个可以选择不会重叠。

我们在插入模式串的时候不区分是哪种类型,在进行find的时候也不进行区分,找到一个模式串以后,同时更新两种类型。只在最后输出的时候区分一下。

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map> using namespace std;
const int maxnode=;
const int sigma_size=;
const int maxs=+;
char T[maxs],P[maxs][],type[maxs];
map<string,int>ms;
int kase;
struct AC_Automata{
int ch[maxnode][sigma_size],val[maxnode],cnt[maxnode][],tim[maxnode];
int f[maxnode],last[maxnode],len[maxnode];
int sz;
void init(){
sz=;
memset(ch[],,sizeof(ch[]));
memset(cnt,,sizeof(cnt));
memset(tim,,sizeof(tim));
val[]=;
ms.clear();
}
void insert(char *s){
int n=strlen(s),u=;
for(int i=;i<n;i++){
int c=s[i]-'a';
if(!ch[u][c]){
ch[u][c]=sz;
memset(ch[sz],,sizeof(ch[sz]));
val[sz++]=;
}
u=ch[u][c];
}
val[u]=;
len[u]=n;
string S=(string)s;
ms[S]=u;
}
void getFail(){
queue<int>q;
f[]=last[]=;
for(int i=;i<sigma_size;i++){
int u=ch[][i];
if(u){
q.push(u);
f[u]=last[u]=;
}
}
while(!q.empty()){
int r=q.front();q.pop();
for(int i=;i<sigma_size;i++){
int u=ch[r][i];
if(!u)continue;
q.push(u);
int v=f[r];
while(v&&!ch[v][i])v=f[v];
f[u]=ch[v][i];
last[u]=val[f[u]]?f[u]:last[f[u]];
}
}
}
void print(int i,int pos){
if(val[i]){
cnt[i][]++;
if(tim[i]+len[i]<=pos){
cnt[i][]++;
tim[i]=pos;
}
print(last[i],pos);
}
}
void find(char *s){
int n=strlen(s),j=;
for(int i=;i<n;i++){
int c=s[i]-'a';
while(j&&!ch[j][c])j=f[j];
j=ch[j][c];
if(val[j])
print(j,i+);
else if(last[j])
print(last[j],i+);
}
}
}ac;
int n;
int main(){
kase=;
while(scanf("%s",T)!=EOF){
++kase;
scanf("%d",&n);
ac.init();
for(int i=;i<=n;i++){
scanf("%d %s",&type[i],P[i]);
ac.insert(P[i]);
}
ac.getFail();
ac.find(T);
printf("Case %d\n",kase);
for(int i=;i<=n;i++){
string S=(string)P[i];
int u=ms[S];
printf("%d\n",ac.cnt[u][type[i]]);
// printf("%d\n",u);
}
printf("\n");
}
return ;
}

【ZOJ 3228】Searching the String 【AC自动机】的更多相关文章

  1. ZOJ 3228 Searching the String(AC自动机)

    Searching the String Time Limit: 7 Seconds      Memory Limit: 129872 KB Little jay really hates to d ...

  2. ZOJ - 3228 Searching the String (AC自己主动机)

    Description Little jay really hates to deal with string. But moondy likes it very much, and she's so ...

  3. ZOJ 3228 Searching the String (AC自己主动机)

    题目链接:Searching the String 解析:给一个长串.给n个不同种类的短串.问分别在能重叠下或者不能重叠下短串在长串中出现的次数. 能重叠的已经是最简单的AC自己主动机模板题了. 不能 ...

  4. ZOJ3228 Searching the String —— AC自动机 + 可重叠/不可重叠

    题目链接:https://vjudge.net/problem/ZOJ-3228 Searching the String Time Limit: 7 Seconds      Memory Limi ...

  5. zoj3228 Searching the String AC自动机查询目标串中模式串出现次数(分可覆盖,不可覆盖两种情况)

    /** 题目:zoj3228 Searching the String 链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=34 ...

  6. ZOJ3228 - Searching the String(AC自动机)

    题目大意 给定一个文本串,接下来有n个模式串,每次查询模式串出现的次数,查询分两种,可重叠和不可重叠 题解 第一次是把AC自动机构造好,跑n次,统计出每个模式串出现的次数,交上去果断TLE...后来想 ...

  7. zoj 3228:Searching the String

    Description Little jay really hates to deal with string. But moondy likes it very much, and she's so ...

  8. ZOJ - 3430 Detect the Virus —— AC自动机、解码

    题目链接:https://vjudge.net/problem/ZOJ-3430 Detect the Virus Time Limit: 2 Seconds      Memory Limit: 6 ...

  9. 【XSY3320】string AC自动机 哈希 点分治

    题目大意 给一棵树,每条边上有一个字符,求有多少对 \((x,y)(x<y)\),满足 \(x\) 到 \(y\) 路径上的边上的字符按顺序组成的字符串为回文串. \(1\leq n\leq 5 ...

  10. hdu 6086 -- Rikka with String(AC自动机 + 状压DP)

    题目链接 Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, s ...

随机推荐

  1. WPF 使用MahApps.Metro UI库

    在WPF中要想使用Metro风格是很简单的,可以自己画嘛.. 但是为了节省时间,哈,今天给大家推荐一款国外Metro风格的控件库. 本文只起到抛砖引玉的作用,有兴趣还是推荐大家上官网,Thanks,官 ...

  2. Cascalog了解

    Cascalog一种能使在Hadoop上使用Clojure处理数据变得简单直观的工具. Cascalog综合了两大顶尖技术:Clojure和Hadoop,同时让Datalog焕发青春. Cascalo ...

  3. 什么是虚拟环境、为什么使用虚拟环境、Anaconda创建、激活、退出、删除虚拟环境

    一.虚拟环境 virtual environment 它是一个虚拟化,从电脑独立开辟出来的环境.通俗的来讲,虚拟环境就是借助虚拟机docker来把一部分内容独立出来,我们把这部分独立出来的东西称作“容 ...

  4. Linux下使用locale命令设置语言环境

    locale命令设置语言环境 在Linux中通过locale来设置程序运行的不同语言环境,locale由 ANSI C提供支持.locale的命名规则为_.,如zh_CN.GBK,zh代表中文, CN ...

  5. jeecg中ajax传值的前端js和后台代码

    前端js: var b=1; $.ajax({ type : "POST", --Post请求方式 url : 'orderController.do?wuliao', --路径 ...

  6. windows下搭建nginx-rtmp服务器

    windows下搭建nginx-rtmp服务器 windows下搭建nginx-rtmp服务器 准备工作 安装MinGW 安装Mercurial 安装strawberryperl 安装nasm 下载n ...

  7. MySQL Join算法与调优白皮书(一)

    正文 Inside君发现很少有人能够完成讲明白MySQL的Join类型与算法,网上流传着的要提升Join性能,加大变量join_buffer_size的谬论更是随处可见.当然,也有一些无知的PGer攻 ...

  8. java代码----------实现创建DataInputStream和DataOutputStream进行读写

    总结: 主要是 捕获异常 package com.a.b; import java.io.*; public class testData { public static void main(Stri ...

  9. zookeeper基本讲解(Java版,真心不错)

    1. 概述 Zookeeper是Hadoop的一个子项目,它是分布式系统中的协调系统,可提供的服务主要有:配置服务.名字服务.分布式同步.组服务等. 它有如下的一些特点: 简单 Zookeeper的核 ...

  10. Mac运维安装软件

    Maccrt软件 sudo spctl --master-disable 打开软件,复制到app,按照sn.txt输入即可 sudo spctl --master-enable crt快捷键crtl ...