先贡献几个数据(没用别怪我):

/*
ab
4
0 ab
1 ab
0 ab
1 ab
abababac
4
0 aba
1 aba
0 abab
1 abab
abcdefghijklmnopqrstuvwxyz
3
0 abc
1 def
1 jmn
abcdabcd
3
0 cd
0 abcd
0 abcd
*/

思路:

因为要考虑不可重复和可重复,而且输入那一堆串还有重复的,如果可以重复,那么就是正常做法,回溯到根,全部相加;如果不可以重复,那么标记位置上的后缀串的长度。

ps:因为是书上例题,然后照着书上代码搞搞搞,没想到搞崩了。因为书上代码是错的!他开了一个flag表示这个位置是否存在后缀串,但是他找的时候= =、第一个错误;还有他没有把fail指针回溯到根,第二个错误,不过这个flag数组搞的很好?(其实并没有。。。贴第一发自己的,第二发书上已改正的代码)

MY CODE

//#include <bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<queue>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII; const int N=1e6+10;
int g[600010][26],word[N],fail[N],sz;
char txt[N],ss[N];
int ans[N][2],last[N],len[N],pos[100010],n,id[100010];
int flag[N]; int INS()
{
int p=0;
int lens=strlen(ss);
int index;
for(int i=0;i<lens;i++){
index=ss[i]-'a';
if(g[p][index]==0){
memset(g[sz],0,sizeof(g[sz]));
last[sz]=-1;
flag[sz]=0;
word[sz]=0;
ans[sz][0]=ans[sz][1]=0;
g[p][index]=sz++;
}
p=g[p][index];
}
word[p]=1;
flag[p]=1;
len[p]=lens;
return p;
} void Build_fail()
{
int p=0;
queue<int>que;
for(int i=0;i<26;i++){
if(g[p][i])
{
que.push(g[p][i]);
fail[g[p][i]]=0;
}
}
while(!que.empty())
{
p=que.front();que.pop();
for(int i=0;i<26;i++){
int u=g[p][i];
if(!u)
g[p][i]=g[fail[p]][i];
else{
que.push(u);
int v=fail[p]; //取父节点的fail指针去匹配
while(v && !g[v][i])
v=fail[v];
fail[u]=g[v][i];
}
}
}
} void solve()
{
int p=0;
int index,lens=strlen(txt);
for(int i=0;i<lens;i++)
{
index=txt[i]-'a';
p=g[p][index];
int temp=p;
while(temp){ //回溯到根
if(word[temp])
{
ans[temp][0]++;
if((i-last[temp])>=len[temp])
{
ans[temp][1]++;
last[temp]=i;
}
}
temp=fail[temp];
}
}
} int main()
{
int cas=1;
while(~scanf("%s",txt))
{
memset(g[0],0,sizeof(g[0]));
sz=1;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%s",&id[i],ss);
pos[i]=INS();
}
Build_fail();
solve();
// for(int i=1;i<sz;i++)
// printf("%d %d\n",ans[i][0],ans[i][1]);
printf("Case %d\n",cas++);
for(int i=1;i<=n;i++)
printf("%d\n",ans[pos[i]][id[i]]);
puts("");
}
return 0;
}

BOOK CODE

//#include <bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<queue>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII; const int N=1e6+10;
int g[600010][26],word[N],fail[N],sz;
char txt[N],ss[N];
int ans[N][2],last[N],len[N],pos[100010],n,id[100010];
int flag[N]; int INS()
{
int p=0;
int lens=strlen(ss);
int index;
for(int i=0;i<lens;i++){
index=ss[i]-'a';
if(g[p][index]==0){
memset(g[sz],0,sizeof(g[sz]));
last[sz]=-1;
flag[sz]=0;
word[sz]=0;
ans[sz][0]=ans[sz][1]=0;
// fail[sz]=0;
g[p][index]=sz++;
}
p=g[p][index];
}
word[p]=1;
flag[p]=1;
len[p]=lens;
return p;
} void Build_fail()
{
int p=0;
queue<int>que;
for(int i=0;i<26;i++){
if(g[p][i])
{
que.push(g[p][i]);
fail[g[p][i]]=0;
}
}
while(!que.empty())
{
p=que.front();que.pop();
for(int i=0;i<26;i++){
int u=g[p][i];
if(!u)
g[p][i]=g[fail[p]][i];
else{
que.push(u);
fail[u]=g[fail[p]][i];
flag[u]|=flag[fail[u]];
}
}
}
} void solve()
{
int p=0;
int index,lens=strlen(txt);
for(int i=0;i<lens;i++)
{
index=txt[i]-'a';
p=g[p][index];
int temp=p;
while(temp&&!flag[temp])
temp=fail[temp];
while(temp){
if(word[temp])
{
ans[temp][0]++;
if((i-last[temp])>=len[temp])
{
ans[temp][1]++;
last[temp]=i;
}
}
temp=fail[temp];
}
}
} int main()
{
int cas=1;
while(~scanf("%s",txt))
{
memset(g[0],0,sizeof(g[0]));
sz=1;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%s",&id[i],ss);
pos[i]=INS();
}
Build_fail();
solve();
printf("Case %d\n",cas++);
for(int i=1;i<=n;i++)
printf("%d\n",ans[pos[i]][id[i]]);
puts("");
}
return 0;
}

ZOJ3228【AC自动机】的更多相关文章

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

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

  2. 【AC自动机】zoj3228 Searching the String

    对所有模式串建立AC自动机. 每个单词结点要记录该单词长度. 然后在跑匹配的时候,对每个单词结点再处理3个值,代表可重叠的匹配次数,不可重叠的匹配次数,以及“上一次不可重叠的匹配位置”,这样结合单词长 ...

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

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

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

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

  5. ZOJ3228 Searching the String (AC自动机)

    Searching the String Time Limit: 7 Seconds                                      Memory Limit: 129872 ...

  6. AC自动机基础知识讲解

    AC自动机 转载自:小白 还可参考:飘过的小牛 1.KMP算法: a. 传统字符串的匹配和KMP: 对于字符串S = ”abcabcabdabba”,T = ”abcabd”,如果用T去匹配S下划线部 ...

  7. 基于trie树做一个ac自动机

    基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...

  8. AC自动机-算法详解

    What's Aho-Corasick automaton? 一种多模式串匹配算法,该算法在1975年产生于贝尔实验室,是著名的多模式匹配算法之一. 简单的说,KMP用来在一篇文章中匹配一个模式串:但 ...

  9. python爬虫学习(11) —— 也写个AC自动机

    0. 写在前面 本文记录了一个AC自动机的诞生! 之前看过有人用C++写过AC自动机,也有用C#写的,还有一个用nodejs写的.. C# 逆袭--自制日刷千题的AC自动机攻克HDU OJ HDU 自 ...

  10. BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2545  Solved: 1419[Submit][Sta ...

随机推荐

  1. EasyRTMP内置进入摄像机中实现网络推流直播摄像机的功能

    本文转自博客:http://blog.csdn.net/jinlong0603/article/details/57468084 在前面的<如何用传统摄像机实现直接对接平台,类似于海康萤石.大华 ...

  2. Java笔记之利用反射访问或修改private成员

    对于类A.B,A是B的基类,A有一个私有成员name A.java public class A { private String name = "A"; public void ...

  3. Factory Pattern

    1.Factory模式两个最重要的功能 (1)定义创建对象的接口,封装了对象的创建. (2)使得具体化类的工作延迟到了子类中. 2.Factory模式结构示意图 3.实现 #ifndef _PRODU ...

  4. 微信小程序开发:学习笔记[9]——本地数据缓存

    微信小程序开发:学习笔记[9]——本地数据缓存 快速开始 说明 本地数据缓存是小程序存储在当前设备上硬盘上的数据,本地数据缓存有非常多的用途,我们可以利用本地数据缓存来存储用户在小程序上产生的操作,在 ...

  5. 需要注意的一些Mysql语句

    1. 日期处理函数:date_format() select COUNT(*) from (SELECT SERIAL_NO, APPLY_SERIAL_NO, FLAG, PAY_DATE, SEQ ...

  6. C#开发遇到的常见问题及知识点

    今天遇到的类型初始值设定项引发异常的原因是:类没有添加[Serializable]属性. this.DialogResult = System.Windows.Forms.DialogResult.O ...

  7. AndroidManifest配置之uses-sdk

    uses-sdk配置 uses-sdk用来设置app对android系统的兼容性.它包含三个可选的配置项,分别为android:minSdkVersion,android:targetSdkVersi ...

  8. Relative atomic mass

    Relative atomic mass Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

  9. MongoDB复制集成员及架构介绍(一)

    MongoDB复制集介绍 MongoDB支持在多个机器中通过异步复制达到提供了冗余,增加了数据的可用性.MongoDB有两种类型的复制,第一种是同于MySQL的主从复制模式(MongoDB已不再推荐此 ...

  10. bzoj 2238 Mst——树链剖分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2238 一条非树边可以对一条链的树边产生影响.注意是边,所以把边下放到点上,只要跳 top 时 ...