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

/*
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. VMware Workstation 14创建mac-10.12虚拟机详细步骤

     一.VMware和unlocker的下载和安装 链接:https://pan.baidu.com/s/15Z4DqRENt6JdyfJef_VWSw 密码:40vw 1.安装VMware Works ...

  2. Windows8-x64 VMWare安装Linux CentOS6-x64

    本文參考了:http://www.cnblogs.com/seesea125/archive/2012/02/25/2368255.html 其内容相当具体,以至于我还没依照其步骤做完.系统就已经安装 ...

  3. asp.net mvc4 之Webapi之客户端或服务器端安全控制

    一.WebAPI的工作方式 WebAPI的工作方式:HTTP的请求最先是被传递到HOST中的,如果WebAPI是被寄宿在IIS上的,这个HOST就是IIS上,HOST是没有能力也没有必 要进行请求的处 ...

  4. 淘宝客网站SEO及赚钱与揭密

  5. 从模版生成 uri Golang 的 html/template 包不太适合于这种情况

    模板 - Go/Golang 框架 Echo 文档 http://go-echo.org/guide/templates/ Templates | Echo - High performance, m ...

  6. Javascript学习之三元运算符详解

    本文主要是通过实例为大家介绍javascript三元运算符相关内容,希望对初学者学习这部分内容有所帮助. 实例 <!DOCTYPE html> <html> <head& ...

  7. meteor---在合并打包多个文件ZIP下载的功能

    实现多个文件边打包边下载的功能,速度还可以,本人亲测,欢迎大家来指点archiver --用NPM安装这个模块---本人文件存储在file-collection 中,可以用fs : fs.create ...

  8. [IR课程笔记]向量空间模型(Vector Space Model)

    VSM思想 把文档表示成R|v|上的向量,从而可以计算文档与文档之间的相似度(根据欧氏距离或者余弦夹角) 那么,如何将文档将文档表示为向量呢? 首先,需要选取基向量/dimensions,基向量须是线 ...

  9. include vector 编译出错VC++

    error C2665: “operator new” : 5个重载中没有一个可以转换参数1(从“const char [71]”类型)这个错误是怎么回事啊,搜索了整个项目好像没有可疑的new操作阿. ...

  10. 人生苦短之Python的urllib urllib2 requests

    在Python中涉及到URL请求相关的操作涉及到模块有urllib,urllib2,requests,其中urllib和urllib2是Python自带的HTTP访问标准库,requsets是第三方库 ...