Searching the String


Time Limit: 7 Seconds                                      Memory Limit: 129872 KB


Little jay really hates to deal with string. But moondy likes it very much, and she's so mischievous that she often gives jay some dull problems related to string. And one day, moondy gave jay another problem, poor jay finally broke out and cried, " Who can help me? I'll bg him! "

So what is the problem this time?

First, moondy gave jay a very long string A. Then she gave him a sequence of very short substrings, and asked him to find how many times each substring appeared in string A. What's more, she would denote whether or not founded appearances of this substring are allowed to overlap.

At first, jay just read string A from begin to end to search all appearances of each given substring. But he soon felt exhausted and couldn't go on any more, so he gave up and broke out this time.

I know you're a good guy and will help with jay even without bg, won't you?

Input

Input consists of multiple cases( <= 20 ) and terminates with end of file.

For each case, the first line contains string A ( length <= 10^5 ). The second line contains an integer N ( N <= 10^5 ), which denotes the number of queries. The next N lines, each with an integer type and a string a ( length <= 6 ), type = 0 denotes substring a is allowed to overlap and type = 1 denotes not.  Note that all input characters are lowercase.

There is a blank line between two consecutive cases.

Output

For each case, output the case number first ( based on 1 , see Samples ).

Then for each query, output an integer in a single line denoting the maximum times you can find the substring under certain rules.

Output an empty line after each case.

Sample Input

ab
2
0 ab
1 ab abababac
2
0 aba
1 aba abcdefghijklmnopqrstuvwxyz
3
0 abc
1 def
1 jmn

Sample Output

Case 1
1
1 Case 2
3
2 Case 3
1
1
0

Hint

In Case 2,you can find the first substring starting in position (indexed from 0) 0,2,4, since they're allowed to overlap.  The second substring starts in position 0 and 4, since they're not allowed to overlap.

For C++ users, kindly use scanf to avoid TLE for huge inputs.

题意:多组数据,首先一串母串,下面是n个模式串,统计各模式串在母串中出现的个数,0表示模式串可交叉,1表示不可以交叉。

思路:0的时候就是普通ac自动机,1的时候有点麻烦。。我干啥用指针。。

   还是统计重复模式串的ans数组,这次得开二维,因为相同的模式串可能有两种情况。在不可交叉的情况下,我们发现一个模式串能再次被统计仅当  本次查找成功的位置-它上次的末尾位置≥查找结束时该字母在字典树的深度。

   其实就是判交叉。。比如ababa(下标从0开始)找aba,第二次查到4处,上次末尾在2,深度3,4-2<3,交叉。

   给每个节点一个编号id用来区分,于是可以用pos数组记录每个模式串的结尾区分模式串,方便最后统计ans,因为这次每个模式串可以有0和1两种形态。loc数组用来记录字典树节点们的深度,last数组记录上一次的统计末尾处,配合loc可以判交叉。

   (枯了 好像数组方便得多)

代码:

#include<bits/stdc++.h>
#define FastIO ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(ll i=a;i<b;i++)
#define repp(i,a,b) for(ll i=a;i<=b;i++)
#define rep1(i,a,b) for(ll i=a;i>=b;i--)
#define mem(gv) memset(gv,0,sizeof(gv))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define QAQ 0
#define miaojie
#ifdef miaojie
#define dbg(args...) do {cout << #args << " : "; err(args);} while (0)
#else
#define dbg(...)
#endif
void err() {std::cout << std::endl;}
template<typename T, typename...Args>
void err(T a, Args...args){std::cout << a << ' '; err(args...);} using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pLL;
const int mod=1e9+;
const int maxn=7e5+; int idd;
struct node
{
node *fail;
node *child[];
int id;
node()
{
fail=NULL;
id=idd++;
for(int i=;i<;i++)
child[i]=NULL;
}
};
int n,op[maxn];
int ans[maxn][],pos[maxn],last[maxn],loc[maxn];
char s1[maxn][];
char s2[maxn];
node *rt; void insert(node *t,char p[],int num)
{
int index,lp=strlen(p),q=;
while(p[q]!='\0')
{
index=p[q]-'a';
if(t->child[index]==NULL)
t->child[index]=new node();
t=t->child[index];
loc[t->id]=q+;
q++;
}
pos[num]=t->id;
} void ac(node *t)
{
queue <node*> q;
t->fail=NULL;
q.push(t);
node *temp;
node *tmp;
int i;
while(!q.empty())
{
temp=q.front();
q.pop();
for(i=;i<;i++)
{
if(temp->child[i]!=NULL)
{
if(temp==t)
temp->child[i]->fail=t;
else
{
tmp=temp->fail;
while(tmp!=NULL)
{
if(tmp->child[i]!=NULL)
{
temp->child[i]->fail=tmp->child[i];
break;
}
tmp=tmp->fail;
}
if(tmp==NULL)
temp->child[i]->fail=t;
}
q.push(temp->child[i]);
}
}
}
} void query(node *t)
{
memset(last,-,sizeof(last));
mem(ans);
int index,q=,len=strlen(s2);
node *p=t;
while(s2[q])
{
index=s2[q]-'a';
while(p->child[index]==NULL &&p!=rt)
p=p->fail;
p=p->child[index];
if(!p) p=rt;
node *tmp=p;
while(tmp!=rt)
{
ans[tmp->id][]++;
if(q-last[tmp->id]>=loc[tmp->id]){
ans[tmp->id][]++;
last[tmp->id]=q;
}
tmp=tmp->fail;
}
q++;
}
} void del(node *root)
{
for(int i=;i<;i++)
if(root->child[i]!=NULL)
del(root->child[i]);
delete root;
root=NULL;
} int main(){
int T=;
while(scanf("%s",s2)!=EOF){
mem(pos); mem(loc); idd=;
rt=new node();
scanf("%d",&n);
repp(i,,n-){
scanf("%d",&op[i]);
scanf("%s",s1[i]);
insert(rt,s1[i],i);
}
ac(rt);
query(rt);
printf("Case %d\n",T++);
repp(i,,n-){
printf("%d\n",ans[pos[i]][op[i]]);
}
del(rt);
printf("\n");
}
return QAQ;
}

ZOJ3228 Searching the String (AC自动机)的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. 【XSY3320】string AC自动机 哈希 点分治

    题目大意 给一棵树,每条边上有一个字符,求有多少对 \((x,y)(x<y)\),满足 \(x\) 到 \(y\) 路径上的边上的字符按顺序组成的字符串为回文串. \(1\leq n\leq 5 ...

  7. hdu 6086 -- Rikka with String(AC自动机 + 状压DP)

    题目链接 Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, s ...

  8. HDU 6096 String (AC自动机)

    题意:给出n个字符串和q个询问,每次询问给出两个串 p 和 s .要求统计所有字符串中前缀为 p 且后缀为 s (不可重叠)的字符串的数量. 析:真是觉得没有思路啊,看了官方题解,真是好复杂. 假设原 ...

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

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

随机推荐

  1. codeforces 724D

    注意到要字典序最小,从而变为水题. 从a选到z,每次必然是先看选部分当前字符x是否能满足覆盖,若不能则选上所有的字母x,不然break,输出答案. 进行26次dp即可. #include <cs ...

  2. kubernetes1.13.1部署ingress-nginx-十一

    一.Ingress 简介 (1) 在Kubernetes中,服务和Pod的IP地址仅可以在集群网络内部使用,对于集群外的应用是不可见的. 为了使外部的应用能够访问集群内的服务, 在Kubernetes ...

  3. 考拉定时任务框架kSchedule

    此文已由作者杨凯明授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 1.背景 目前项目中使用的定时任务框架存在下面这些问题 没有统一的定时任务管理平台 目前项目中使用定时任务的 ...

  4. CCF2016.4 - C题

    思路:先把路径按反斜杠split成数组,然后用一个ArrayList去模拟.如果遇到空或者.则不处理:如果遇到..则删除ArrayList最后一个元素(注意如果只有1个元素则不删除):其他情况直接加到 ...

  5. java 强大的反射机制

    这段时间,在对接一个开源的版本时,发现由于依赖的开源版本api老是随着版本的变化而变化,导致代码经常需要修改,异常痛苦. 终于,在一个风和日丽的下午(五月末的广州异常暴晒),楼主下定决心要修掉这个大篓 ...

  6. 基于 React-draft-wysiwyg 实现的 react 富文本编辑器组件 开箱即用

    工作中遇到了一个需要做图文详情 的富文本编辑的需求, 于是基于 React-draft-wysiwyg 实现了一个 纯组件, 目前支持 常规文本输入 外部链接图片 以及本地上传图片, 由于是纯组件, ...

  7. Java 反射机制详解(下)

    续:Java 反射机制详解(上) 三.怎么使用反射 想要使用反射机制,就必须要先获取到该类的字节码文件对象(.class),通过字节码文件对象,就能够通过该类中的方法获取到我们想要的所有信息(方法,属 ...

  8. PHP + jquery.validate remote的用法

    [ 转 ] http://www.cnlvzi.com/index.php/Index/article/id/58 最近做验证功能时,用到jquery.validate.js中的remote远程验证方 ...

  9. hdu 3367 Pseudoforest 最大生成树★

    #include <cstdio> #include <cstring> #include <vector> #include <algorithm> ...

  10. safari 日期显示NAN

    解决方案: 1.服务器端将时间转换为时间戳,前端再进行处理,问题解决. fastjson,JSON.toJSONString() 自动将时间字段转换为时间戳类型,然后传到前端. @RequestMap ...