/**
题目:zoj3228 Searching the String
链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3441
题意:给定一个长度为N(N <= 105)的目标串,然后再给定M(M <= 105)个长度不大于6的字符串, 问这些字符串在目标串的出现次数(分可重叠和不可重叠两种)。 题解:可以覆盖情况下,直接建立自动机求次数。注意可能出现类型相同以及字符串相同。所以用map标记; 不可以覆盖情况下,直接建立自动机,查询的时候维护当前查到的字符串上一次找到的位置lastpos. 如果lastpos+该子串长度<=pos那么可以ans++,以及更新lastpos=pos; find(),find2()两个函数分别处理可覆盖,不可覆盖情况。先统一处理可覆盖,然后清空自动机重新构建不可覆盖情况下的自动机。 AC自动机好文章:http://www.cppblog.com/menjitianya/archive/2014/07/10/207604.html
*/ //#include<bits/stdc++.h>
#include<cstring>
#include<cstdio>
#include<iostream>
#include<map>
#include<algorithm>
#include<queue>
using namespace std;
#define P pair<int,int>
#define ms(x,y) memset(x,y,sizeof x)
#define LL long long
const int maxn = ;
const int mod = 1e9+;
const int maxnode = *+;
const int sigma_size = ;
map<string,int> mp1, mp2;
struct node
{
char s[];
int type;
int len;
int ans;
int lastpos;
}t[];
struct AhoCorasickAutomata
{
int ch[maxnode][sigma_size];
int val[maxnode];
int sz;
int f[maxnode];
int last[maxnode];
void clear(){sz = ; memset(ch[],,sizeof ch[]); }
int idx(char c){return c-'a'; } void insert(char *s,int x)
{
int u = , n = strlen(s);
for(int i = ; i < n; i++){
int c = idx(s[i]);
if(!ch[u][c]){
memset(ch[sz], , sizeof ch[sz]);
val[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = x;
} void find(char* T){
int j = ;
for(int i = ; T[i]!='\0'; i++){
int c = idx(T[i]);
j = ch[j][c];
if(val[j]) print(j);
else if(last[j]) print(last[j]);
}
} void print(int j)
{
if(j){
//cnt[val[j]]++;
t[val[j]].ans++;
print(last[j]);
}
} void find2(char* T){///不可覆盖情况下;
int j = ;
for(int i = ; T[i]!='\0'; i++){
int c = idx(T[i]);
j = ch[j][c];
if(val[j]) print2(j,i);
else if(last[j]) print2(last[j],i);
}
} void print2(int j,int pos)
{
if(j){
//cnt[val[j]]++;
if(t[val[j]].lastpos+t[val[j]].len<=pos){
t[val[j]].ans++;
t[val[j]].lastpos = pos;
}
print2(last[j],pos);
}
} void getFail(){
queue<int> q;
f[] = ;
for(int c = ; c < sigma_size; c++){
int u = ch[][c];
if(u){f[u] = ; q.push(u); last[u] = ;}
} while(!q.empty()){
int r = q.front(); q.pop();
for(int c = ; c < sigma_size; c++){
int u = ch[r][c];
if(!u){
ch[r][c] = ch[f[r]][c]; continue;
}//if(!u) continue;
q.push(u);
int v = f[r];
while(v&&!ch[v][c]) v = f[v];
f[u] = ch[v][c];
last[u] = val[f[u]] ? f[u] : last[f[u]];
}
}
} } ac;
char s[];
int main()
{
int cas = ;
while(scanf("%s",s)==)
{
int n;
scanf("%d",&n);
ac.clear();
mp1.clear();
mp2.clear();
for(int i = ; i <= n; i++){
scanf("%d%s",&t[i].type,t[i].s);
t[i].ans = ;
if(t[i].type==){
mp1[string(t[i].s)] = i;
ac.insert(t[i].s,i);
}
}
ac.getFail();
ac.find(s);
ac.clear();
mp2.clear();
for(int i = ; i <= n; i++){
if(t[i].type){
t[i].len = strlen(t[i].s);
t[i].lastpos = -;
mp2[string(t[i].s)] = i;
ac.insert(t[i].s,i);
}
}
ac.getFail();
ac.find2(s);
printf("Case %d\n",cas++);
for(int i = ; i <= n; i++){
if(t[i].type){
printf("%d\n",t[mp2[t[i].s]].ans);
}else
{
printf("%d\n",t[mp1[t[i].s]].ans);
}
}
printf("\n");
}
return ;
} /* */

zoj3228 Searching the String AC自动机查询目标串中模式串出现次数(分可覆盖,不可覆盖两种情况)的更多相关文章

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

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

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

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

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

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

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

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

  5. 2017多校第6场 HDU 6096 String AC自动机

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6096 题意:给了一些模式串,然后再给出一些文本串的不想交的前后缀,问文本串在模式串的出现次数. 解法: ...

  6. HDU - 2222,HDU - 2896,HDU - 3065,ZOJ - 3430 AC自动机求文本串和模式串信息(模板题)

    最近正在学AC自动机,按照惯例需要刷一套kuangbin的AC自动机专题巩固 在网上看过很多模板,感觉kuangbin大神的模板最为简洁,于是就选择了用kuangbin大神的模板. AC自动机其实就是 ...

  7. sql 查询目标数据库中所有的表以其关键信息

    1.查询目标库中的所有表 SELECT obj.name tablename, ---表名 schem.name schemname, ---表所属的方案 idx.rows, ---一共有几行数组 C ...

  8. Searching the String ZOJ - 3228 AC自动机查询升级版

    题意:先给你一个不超过1000000长度的大串s:接下来输入一个n代表接下来输入的小串个数,小串长度不超过6. 小串分两种类型0和1类型. 0类型表示小串在大串中的最大匹配个数就是常规的AC自动机的做 ...

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

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

随机推荐

  1. Python 的 pass 语句

    Python pass是空语句,是为了保持程序结构的完整性. pass 不做任何事情,一般用做占位语句. 例子1: if __name__ == '__main__': pass 例子2: # 输出 ...

  2. LeetCode-342:Power of Four

    This  is another  "Pick One" Problem :[Problem:342-Power of Four] Given an integer (signed ...

  3. 漫谈Github与开源,Git介绍以及Git的思想和基本工作原理 Git工作流程

    漫谈Github与开源 文字亮点: 为什么这些优秀的工程师会开源自己的项目? 因为开源是一种精神. 无数的软件开发者苦心积虑保护自己的代码不被破解,而还是被聪明绝顶的脚本小子破解了,但破解无数软件的脚 ...

  4. Java虚拟机学习 - 垃圾收集算法(3)

    跟踪收集器       跟踪收集器采用的为集中式的管理方式,全局记录对象之间的引用状态,执行时从一些列GC  Roots的对象做为起点,从这些节点向下开始进行搜索所有的引用链,当一个对象到GC  Ro ...

  5. (转)Stack Overflow 2016最新架构探秘

    这篇文章主要揭秘 Stack Overflow 截止到 2016 年的技术架构. 首先给出一个直观的数据,让大家有个初步的印象. 相比于 2013 年 11 月,Stack Overflow 在 20 ...

  6. WEB网络问题的排查【转】

    Browser/Server结构主要是利用了不断成熟的Web浏览器技术:结合浏览器的多种脚本语言和ActiveX技术,用通用浏览器实现原来需要复杂专用软件才能实现的强大功能,同时节约了开发成本.B/S ...

  7. Hadoop DistCp 使用指南

    原文地址:http://hadoop.apache.org/docs/r1.0.4/cn/distcp.html 概述 使用方法 基本使用方法 选项 选项索引 更新和覆盖 附录 Map数目 不同HDF ...

  8. PSQL_标准API和Interface基本的用法和比较(概念)

    2014-01-05 Created By BaoXinjian

  9. OGG_GoldenGate数据表定义方式DEFGEN(案例)

    2014-03-09 Created By BaoXinjian

  10. t:formvalid中定义callback函数

    如果dialog="true"的话       callback="@Override functionName" 调用的是当前页面的方法       call ...