题意

给出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. Windows下安装Redis服务,修改查看密码,修改端口,常用命令

    一.安装 出自:https://jingyan.baidu.com/article/0f5fb099045b056d8334ea97.html 1.要安装Redis,首先要获取安装包.Windows的 ...

  2. android 自己定义checkbox 背景图无效的问题

    http://blog.csdn.net/zuolongsnail/article/details/7106586  正常的定义能够參考这个网址  可是我參考它以后发现我执行时候 根本不工作嘛  结果 ...

  3. qqbot 配置

    qqbot 配置 用起来还是挺方便的,使用 pip install qqbot 就可以. 不过找配置文件没注意,以为是在程序目前,原来是在 C:\Users\xxx.qqbot-tmp 目录. 插件可 ...

  4. Kubernetes基本概念

    Kubernete模型中的核心概念.这些核心概念反映了Kubernetes设计过程中对应用容器集群的认知模型. 集群组件,从架构上看,Kubernetes集群(Cluster)也采用了典型的“主-从” ...

  5. git忽略已经提交的文件【转载】

    有时候我们添加.gitignore文件之前已经提交过了文件..gitignore只能忽略那些原来没有被track的文件(自添加以后,从未 add 及 commit 过的文件),如果某些文件已经被纳入了 ...

  6. (转)Linux安装SwfTools-0.9.2安装事,在执行make install时报错

    系统:CentOS6.5 安装SwfTools-0.9.2的时候,在执行make install时报错, rm -f /usr/local/share/swftools/swfs/default_vi ...

  7. elasticsearch 6.0.0及之后移除了一个索引允许映射多个类型的操作(Removal of mapping types)

    分给线一下内容为理解错误内容,实际允许建立父子分档,只是类型改成来 join 官方demo: join datatypeedit The join datatype is a special fiel ...

  8. mysql索引相关理解

    1.索引是高效获取数据的数据结构, 2.唯一索引,索引值不重复unique create unique index 索引名 on 表名(字段) alter table 表名 add unique in ...

  9. POJ1745动态规划

    Divisibility Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11622   Accepted: 4178 Des ...

  10. Firewalld的panic模式

    原文地址:http://www.excelib.com/article/289/show Firewalld有一种Panic模式,Panic的单词含义为“恐慌”.“惊慌”,在firewalld中他表示 ...