题意:

给你一个模板串, 和n 个要匹配的串, 匹配串有两种类型, 第一种 可以在模板串中 重叠 出现, 另一种不可以重叠, 问每个串的两种形式 所出现的数量。

思路:

很明显ac自动机。

我们先把所有匹配串插到自动机中, 第一种很简单 ,可以重叠出现, 直接循环一边模板串, 不断的走fail 指针 , 找到一个 加一个就行了。

不可重叠也很简单, 直接在开一个last数组 ,表示这个单词 上一次出现是啥时候, 只要两次位置差不小于单词长度即可。

一开始给每个字典树的节点 开了个vector, 记录这个节点中都有哪些输入的单词, 但是T了。

不如 把所有情况都查找一边,  无论输入的单词是哪种类型, 我们把两种类型都查找一遍即可。  只是走一遍ac自动机而已。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;const int maxn = 100000 + 10;const int maxt = maxn * 6;char s[maxn];int type[maxn]; /// 每个输入的单词  的类型 0/1
int ans[maxt][2];
struct Trie{int L, root;int next[maxt][26];int fail[maxt];int last[maxt]; ///记录每个单词 上一次出现是啥时候int d[maxt]; /// 记录字典树中的节点 到根的距离(即单词的长度)int flag[maxt]; /// 是否是单词int pos[maxt]; /// 每个输入的单词 在字典树中的位置。void init(){L = 0;root = newnode();}int newnode(){for (int i = 0; i < 26; ++i){next[L][i] = -1;}d[L] = 0;flag[L] = 0;ans[L][0] = ans[L][1] = 0;return L++;}void insert(char* s, int id){int len = strlen(s);int nod = root;for (int i = 0; i < len; ++i){int id = s[i] - 'a';if (next[nod][id] == -1){next[nod][id] = newnode();}d[next[nod][id] ] = d[nod] + 1;nod = next[nod][id];}pos[id] = nod;flag[nod] = 1;}void bfs(){fail[root] = root;queue<int>q;for (int i = 0; i < 26; ++i){if (next[root][i] == -1){next[root][i] = root;}else {fail[next[root][i] ] = root;q.push(next[root][i]);}}while(!q.empty()){int u = q.front(); q.pop();for (int i = 0; i < 26; ++i){if (next[u][i] == -1){next[u][i] = next[fail[u] ][i];}else {fail[next[u][i] ] = next[fail[u] ][i];q.push(next[u][i]);}}}}void solve(char* s,int n){int len = strlen(s);int nod = root;for (int i = 0; i < L; ++i){last[i] = -1;}for (int i = 0; i < len; ++i){int id = s[i] - 'a';nod = next[nod][id];int tmp = nod;while(tmp != root){if (flag[tmp]){ans[tmp][0]++;if (last[tmp] == -1 || i - last[tmp] >= d[tmp]){last[tmp] = i;ans[tmp][1]++;}}tmp = fail[tmp];}}for (int i = 0; i < n; ++i){printf("%d\n", ans[pos[i] ][type[i] ]);}}}ac;
char word[7];
int main(){int ks = 0;while(~scanf("%s", s)){int n;scanf("%d",&n);ac.init();memset(ans, 0, sizeof ans);for (int i = 0; i < n; ++i){scanf("%d%s", &type[i], word);ac.insert(word, i);}ac.bfs();printf("Case %d\n", ++ks);ac.solve(s, n);printf("\n");}return 0;
}
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 typeand 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 ababababac
2
0 aba
1 abaabcdefghijklmnopqrstuvwxyz
3
0 abc
1 def
1 jmn

Sample Output

Case 1
1
1Case 2
3
2Case 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.


Author:  LI, Jie
Source:  ZOJ Monthly, July 2009
Submit     Status

Copyright @ 2001-2017, Zhejiang University ACM/ICPC Team, All rights reserved.

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 typeand 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 ababababac
2
0 aba
1 abaabcdefghijklmnopqrstuvwxyz
3
0 abc
1 def
1 jmn

Sample Output

Case 1
1
1Case 2
3
2Case 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.


Author:  LI, Jie
Source:  ZOJ Monthly, July 2009
Submit     Status

Copyright @ 2001-2017, Zhejiang University ACM/ICPC Team, All rights reserved.

ZOJ 3228 Searching the String (AC自动机)相关推荐

  1. ZOJ - 3228 Searching the String(AC自动机求不重复子串出现次数)

    题目链接:点击查看 题目大意:给出一个匹配串 str ,再给出 n 个长度不大于 6 的匹配串 s ,问每个匹配串出现的次数,分可以重复或不可以重复两种情况 题目分析:因为是匹配串在模式串中出现的次数 ...

  2. zoj-3228 Searching the String AC自动机

    用一个val数组记录每一个单词结尾对应的位置,pos数组记录某个节点的深度(其实就是记录单词的长度的),然后用一个op数组记录一下每一个单词对应的询问方式,主要是查询分为了可重叠和不可重叠,不可重叠的 ...

  3. hdu 6086 Rikka with String(AC自动机+状压dp)

    题目链接:hdu 6086 Rikka with String 题意: 给你n个只含01的串,和一个长度L,现在让你构造出满足s[i]≠s[|s|−i+1] for all i∈[1,|s|] ,长度 ...

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

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

  5. A. chino with string(ac自动机+floyd矩阵快速幂)

    LINK 有mmm个字符串,每个字符串有一定的分值(可能为负数) 求出一个长nnn的字符串sss使得它的价值最大,你只需要输出这个最大的价值. 价值定义为∑i=1mcii∗pointi\sum\lim ...

  6. 转自kuangbin的AC自动机(赛前最后一博)

    有了KMP和Trie的基础,就可以学习神奇的AC自动机了.AC自动机其实就是在Trie树上实现KMP,可以完成多模式串的匹配.           AC自动机 其实 就是创建了一个状态的转移图,思想很 ...

  7. ZOJ 3228(AC自动机+修改的匹配)

    题目大意:给出一个字符串和若干个单词,问这些单词在字符串里面出现了多少次.单词前面为0表示这个单词可重叠出现,1为不可重叠出现. 分析:可重叠出现的单词可以直接用ac自动机就解决.至于不可重叠的单词, ...

  8. CodeForces - 1252D Find String in a Grid(AC自动机)

    题目链接:点击查看 题目大意:给出一个 n * m 的字符矩阵,再给出 q 次询问,每次询问需要回答给出字符串在字符矩阵中出现了多少次,规定在字符矩阵中查找某个字符串,只能先向右 a 个单位,再向下 ...

  9. 石油大--Contest2022 - 2020年秋季组队训练赛第二场--17100 Problem D、Find String in a Grid (AC自动机)

    题面: 题意: 给定一个 R∗CR*CR∗C 的字符矩阵,由大写字母构成. 有 qqq 个询问,每次给定一个由大写字母构成的字符串,问这个字符串在这个字符矩阵中出现了多少次. 某个字符串在矩阵中出现定 ...

最新文章

  1. blf文件用什么软件打开_如何用皕杰流程创建一个blf演示流程文件?
  2. 英国前首相:为什么欧洲没有诞生互联网巨头?
  3. Cissp-【第4章 通信与网络安全】-2021-3-14(476页-542页)
  4. 网站SEO优化之如何维护网站权重?
  5. html网页大小自动调整大小,根据电脑屏幕分辩率大小自动调整网页宽度
  6. 多线程中堆和栈区别的深入解析
  7. Mozilla考虑支持H.264
  8. 我不够格,但我还是希望事情到此为止,继续工作罢
  9. (51)Verilog HDL上升沿检测
  10. 12306能删候补订单记录_2019最新火车候补购票十大问题
  11. Opencv结合socket进行视频传输(TCP协议)
  12. H.265 SAO技术
  13. 志强:微商微信如何引流加人?
  14. 产品经理需要看懂接口文档么?
  15. android rar文件怎么打开方式,rar文件手机上怎么打开 手机怎么打开zip文件
  16. Js基础引导(二)——语法
  17. SpringMVC中使用hibernate-validator的坑
  18. Ubuntu下编译VeraCrypt
  19. Ajaxfileupload上传多张图片
  20. android进入相机不显示缩略图,无法显示图片,缩略图可以

热门文章

  1. C++:include:理解 C++ 中的头文件和源文件的作用
  2. 怎么提升社群转化率?
  3. Docker——Docker in Docker原理与实战
  4. Android 代码检查工具SonarQube
  5. ImmunoChemistry艾美捷基本细胞毒性试验试剂盒测定方案
  6. NodeJS应用部署之PM2(充分利用多核cpu)
  7. mysql数据更新回退_MySQL 8 事务管理、数据库维护、改善性能
  8. 如何让多个版本的Python和谐共处
  9. 学习笔记(01):无人驾驶--从零入门实战视频教程-光学雷达在无人驾驶技术中应用...
  10. query string 查询