zoj3228 Searching the String AC自动机查询目标串中模式串出现次数(分可覆盖,不可覆盖两种情况)
/**
题目: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自动机查询目标串中模式串出现次数(分可覆盖,不可覆盖两种情况)的更多相关文章
- 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...后来想 ...
- ZOJ 3228 Searching the String(AC自动机)
Searching the String Time Limit: 7 Seconds Memory Limit: 129872 KB Little jay really hates to d ...
- ZOJ3228 Searching the String (AC自动机)
Searching the String Time Limit: 7 Seconds Memory Limit: 129872 ...
- 2017多校第6场 HDU 6096 String AC自动机
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6096 题意:给了一些模式串,然后再给出一些文本串的不想交的前后缀,问文本串在模式串的出现次数. 解法: ...
- HDU - 2222,HDU - 2896,HDU - 3065,ZOJ - 3430 AC自动机求文本串和模式串信息(模板题)
最近正在学AC自动机,按照惯例需要刷一套kuangbin的AC自动机专题巩固 在网上看过很多模板,感觉kuangbin大神的模板最为简洁,于是就选择了用kuangbin大神的模板. AC自动机其实就是 ...
- sql 查询目标数据库中所有的表以其关键信息
1.查询目标库中的所有表 SELECT obj.name tablename, ---表名 schem.name schemname, ---表所属的方案 idx.rows, ---一共有几行数组 C ...
- Searching the String ZOJ - 3228 AC自动机查询升级版
题意:先给你一个不超过1000000长度的大串s:接下来输入一个n代表接下来输入的小串个数,小串长度不超过6. 小串分两种类型0和1类型. 0类型表示小串在大串中的最大匹配个数就是常规的AC自动机的做 ...
- 【AC自动机】zoj3228 Searching the String
对所有模式串建立AC自动机. 每个单词结点要记录该单词长度. 然后在跑匹配的时候,对每个单词结点再处理3个值,代表可重叠的匹配次数,不可重叠的匹配次数,以及“上一次不可重叠的匹配位置”,这样结合单词长 ...
随机推荐
- PAT 1085 Perfect Sequence
PAT 1085 Perfect Sequence 题目: Given a sequence of positive integers and another positive integer p. ...
- Google地图之OverlayView使用(自定义叠加层)
Google Maps API 第 3 版提供了用于创建自定义叠加层的 OverlayView 类.OverlayView 是一个基类,提供了您在创建叠加层时必须实现的若干方法.该类还提供了一些方法, ...
- Android调试技巧之Eclipse行号和Logcat
很多初入Android的开发者可能会发现经常遇到Force Close或ANR这样的问题,一般我们通过Android系统的错误日志打印工具Logcat可以看到出错的内容,今天一起来说下如何通过 Ecl ...
- Unix环境高级编程(八)进程关系
本章看后给人似懂非懂的感觉,主要是不知道实际当中如何去使用.通过前面几章的学习,每个进程都有一个父进程,当子进程终止时,父进程得到通知并取得子进程的退出状态.先将本章基本的知识点总结如下,日后再看时候 ...
- bug list
机型: Samsung Galaxy S GT-I9000 版本: 2.2.1bug: Couldn't create directory for SharedPreferences file xxx ...
- mysql 添加列的索引
无论哪种模式加入索引.会大幅度增加SELECT速度 索引名:Index_User_Name 栏目名:user_name 索引类型:Nornal 索引方式:BTREE
- Spring中的内部Bean
简介 当一个bean仅被用作另一个bean的属性时,它能被声明为一个内部bean,为了定义inner bean,在Spring 的 基于XML的 配置元数据中,可以在 <property/> ...
- 几种常见排序算法之Java实现(插入排序、希尔排序、冒泡排序、快速排序、选择排序、归并排序)
排序(Sorting) 是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个关键字有序的序列. 稳定度(稳定性)一个排序算法是稳定的,就是当有两个相等记录的关 ...
- HDU 1260 Tickets (动规)
Tickets Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Su ...
- git将远程仓库最新版本拉到本地仓库
一.正规做法有两种.git fetch和git pull. 注意不管用fetch还是pull,做之前都要在本地仓库做一次git commit,确保,本地仓库和工作目录及缓存一致.1.git fetch ...