ZOJ3228【AC自动机】
先贡献几个数据(没用别怪我):
/*
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自动机】的更多相关文章
- zoj3228 Searching the String AC自动机查询目标串中模式串出现次数(分可覆盖,不可覆盖两种情况)
/** 题目:zoj3228 Searching the String 链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=34 ...
- 【AC自动机】zoj3228 Searching the String
对所有模式串建立AC自动机. 每个单词结点要记录该单词长度. 然后在跑匹配的时候,对每个单词结点再处理3个值,代表可重叠的匹配次数,不可重叠的匹配次数,以及“上一次不可重叠的匹配位置”,这样结合单词长 ...
- ZOJ3228 Searching the String —— AC自动机 + 可重叠/不可重叠
题目链接:https://vjudge.net/problem/ZOJ-3228 Searching the String Time Limit: 7 Seconds Memory Limi ...
- ZOJ3228 - Searching the String(AC自动机)
题目大意 给定一个文本串,接下来有n个模式串,每次查询模式串出现的次数,查询分两种,可重叠和不可重叠 题解 第一次是把AC自动机构造好,跑n次,统计出每个模式串出现的次数,交上去果断TLE...后来想 ...
- ZOJ3228 Searching the String (AC自动机)
Searching the String Time Limit: 7 Seconds Memory Limit: 129872 ...
- AC自动机基础知识讲解
AC自动机 转载自:小白 还可参考:飘过的小牛 1.KMP算法: a. 传统字符串的匹配和KMP: 对于字符串S = ”abcabcabdabba”,T = ”abcabd”,如果用T去匹配S下划线部 ...
- 基于trie树做一个ac自动机
基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...
- AC自动机-算法详解
What's Aho-Corasick automaton? 一种多模式串匹配算法,该算法在1975年产生于贝尔实验室,是著名的多模式匹配算法之一. 简单的说,KMP用来在一篇文章中匹配一个模式串:但 ...
- python爬虫学习(11) —— 也写个AC自动机
0. 写在前面 本文记录了一个AC自动机的诞生! 之前看过有人用C++写过AC自动机,也有用C#写的,还有一个用nodejs写的.. C# 逆袭--自制日刷千题的AC自动机攻克HDU OJ HDU 自 ...
- BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2545 Solved: 1419[Submit][Sta ...
随机推荐
- Storage,Memcache,KVDB都是存储服务,如何区分何时用何种服务
Storage :是SAE为开发者提供的分布式文件存储服务,用来存放用户的持久化存储的文件.用户需要先在在线管理平台创建Domain(相当于一级子目录). Storage为开发者提供分布式文件存 ...
- 【Web探索之旅】第三部分第一课:server
wx_fmt=jpeg" alt="0? wx_fmt=jpeg" style="height:auto"> 内容简单介绍 .第三部分第一课:s ...
- iOS8需要兼容的内容
本文转载至 http://blog.csdn.net/liuwuguigui/article/details/39494435 1.iPad上使用presentModalViewController ...
- 【BZOJ2729】[HNOI2012]排队 组合数
[BZOJ2729][HNOI2012]排队 Description 某中学有 n 名男同学,m 名女同学和两名老师要排队参加体检.他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那 ...
- FireMonkey下的WndProc实现
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Types, System.UI ...
- Java服务器端 API 错误码设计总结
1.对于API结果返回,定义BaseResult 类 拥有success,errorCode,errorMsg个3个基本参数,success使用Boolean类型,errorCode使用Integer ...
- 关于ActiveMQ接收端停止接收的方法
现在有一个需求: 在发送端服务器出现故障后,接收端的接收方法要停下来,关于停止接收的方法,我做了下面这些事情: // 获取 ConnectionFactory ConnectionFactory co ...
- 【LeetCode】Search in Rotated Sorted Array II(转)
原文链接 http://oj.leetcode.com/problems/search-in-rotated-sorted-array-ii/ http://blog.csdn.net/linhuan ...
- socket基本使用
UDP发送和接收 MainRecv.cpp #include <iostream> #include <WinSock2.h> #include <sstream> ...
- Spring 配置JNDI数据源
1.Spring 提供的JNDI调用类. 2.使用weblogic进行部署项目,所以使用WebLogicNativeJdbcExtrator类进行配置. 3.配置完数据源后配置sessionFacto ...