题意:

给定T个测试数据

n个操作

+ 插入单词

? 询问母串中有多少个子串 在上面出现过

( 子串被加密,即←移动L位 (L为上次询问的答案) )

分块思路:

因为模式串和母串交叉给出,正常来说应该是,每次询问前都要getFail,这样显然会超时)

所以我们用一个小型ac自动机 buf , 每次插入都插入到 buf 中,并重建一下buf 的getFail

若buf的节点数 > 2000,则把其中节点添加到 ac自动机上

时间复杂度为 O(n*sqrt(n)) ,详见tao哥题解:http://blog.csdn.net/no__stop/article/details/16823479

geiFail一次 时间为 当前自动机上的节点数

#pragma comment( linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define maxnode 511111
#define sigma_size 2
struct Trie{
int ch[maxnode][sigma_size];
bool val[maxnode];
int f[maxnode];
int sz;
void init(){
sz=1;
memset(ch,0,sizeof(ch));
memset(val, 0, sizeof(val));
memset(f,0,sizeof(f));
}
int idx(char c){ return c-'0'; }
int insert(char *s){
int u = 0;
for(int i = 0; s[i] ;i++){
int c = idx(s[i]);
if(!ch[u][c])
ch[u][c] = sz++;
u = ch[u][c];
}
val[u] = 1;
return u;
}
bool search(char *s){
int u = 0;
for(int i = 0; s[i] ;i++){
int c = idx(s[i]);
if(!ch[u][c]) return 0;
u = ch[u][c];
}
return val[u];
}
void getFail(){
queue<int> q;
for(int i = 0; i<sigma_size; i++)
if(ch[0][i]) q.push(ch[0][i]);
while(!q.empty()){
int r = q.front(); q.pop();
for(int c = 0; c<sigma_size; c++){
int u = ch[r][c];
if(!u)continue;
q.push(u);
int v = f[r];
while(v && ch[v][c] == 0) v = f[v]; //沿失配边走上去 如果失配后有节点 且 其子节点c存在则结束循环
f[u] = ch[v][c];
}
}
}
int find(char *T){
int j = 0, ans = 0;
for(int i = 0; T[i] ; i++){
int c = idx(T[i]);
while(j && ch[j][c]==0) j = f[j];
j = ch[j][c];
int temp = j;
while(temp){ //沿失配边走 || 若沿失配边走时一定要节点为单词结尾则改成while(temp && val[temp])
ans += val[temp];
temp = f[temp];
}
}
return ans;
}
};
Trie ac, buf;
void dfs(int u, int v){
for(int i = 0;i < 2;i++){
if( buf.ch[v][i] )
{
int e2 = buf.ch[v][i];
if(! ac.ch[u][i])
{
memset(ac.ch[ac.sz], 0, sizeof(ac.ch[ac.sz]));
ac.ch[u][i] = ac.sz++;
}
int e1 = ac.ch[u][i];
ac.val[e1] |= buf.val[e2];
dfs(e1, e2);
}
}
}
void join(){
dfs(0, 0);
buf.init();
ac.getFail();
}
char s[6000000],temp[6000000];
int main(){
int Cas = 1, T, n;scanf("%d",&T);
while(T--){
scanf("%d",&n);
printf("Case #%d:\n",Cas++);
ac.init();
buf.init();
int L = 0;
while(n--){
scanf("%s",temp);
int len = strlen ( temp + 1 ) ;
s[0] = temp[0] ;
for (int i = 0 ; i < len ; i ++ )
s[i+1] = temp[1+(i+L%len+len)%len] ;
s[len+1] = '\0';
if(s[0] == '+'){
if( buf.search(s+1) || ac.search(s+1) )continue;//若单词已存在
buf.insert(s+1);
buf.getFail();
if(buf.sz > 2000) join();
}
else
{
L = buf.find(s+1) + ac.find(s+1);
printf("%d\n", L);
}
}
}
return 0;
}
/*
/*
99
10
+01
+110
?010
+110
+00
+0
?001001
?001001
+110110
?1101001101
6
+01
+110
+110
+00
+0
?001001
20
+101001011
?110100
+11010100
?0011001101
+111011
?00010011
+0111010110
+0000101
+0
+11000
?1
+1010101
+0001
+0110
+0111101111
?1100
+0111
+1001
?0110111011
?1010010100
10
+00
?010110100
+0100000100
+111
+000000
?0000110
+110
+00
+0011
?101001
99
+0
+1000100
+01
+0
?1110010011
ans:
case 1
1
7
7
11
case 2
8
*/

HDU 4787 在线AC自动机 分块(模式串和母串交叉给出,多次求getFail)相关推荐

  1. AC自动机 - 多模式串的匹配 --- HDU 3695 Computer Virus on Planet Pandora

    Problem's Link Mean: 有n个模式串和一篇文章,统计有多少模式串在文章中出现(正反统计两次). analyse: 好久没写AC自动机了,回顾一下AC自动机的知识. 本题在构造文章的时 ...

  2. Keywords Search HDU - 2222(AC自动机模板)

    题意: 给定 n个长度不超过 50的由小写英文字母组成的单词准备查询,以及一篇文章,问:文中出现了多少个待查询的单词.多组数据. 题目: In the modern time, Search engi ...

  3. HDU 2296 Ring AC自动机 + DP

    题意:给你n个模式串,每个模式串有一个得分,让你构造出一个长度为N之内且分数最高的文本串;输出字典序列最小的. 解题思路:  AC自动机 + DP , 不过要输出字典序列最小,多开一个 一个三维字符串 ...

  4. hdu 6096---String(AC自动机)

    题目链接 Problem Description Bob has a dictionary with N words in it. Now there is a list of words in wh ...

  5. HDU - 2296 Ring(AC自动机+dp)

    题目链接:点击查看 题目大意:给出 n 个字符串,每个字符串都有一个权值,现在问在组成字符串长度不超过 m 的前提下,怎样构造才能使得出现的字符串权值和最大,在满足上个条件的基础上长度最短,如果依然有 ...

  6. hdu 2604 Queuing AC自动机构造递推式-矩阵-结果

    http://acm.hdu.edu.cn/showproblem.php?pid=2604 题意: L个人排队,这一队里男性用m表示,女性用f表示,问长度为L的序列里面不包含形如"fmf& ...

  7. HDU 3058 Generator [AC自动机+期望DP]

    给出M个短串,这些短串由前N个大写字母组成.然后随机的按字符生成字符串,每次生成1~N个字符的概率是相等的,当生成串包含任意一个指定短串时,就停止生成.问生成串的长度的期望是多少. 首先建立Trie图 ...

  8. hdu 2896 病毒侵袭(AC自动机)

    病毒侵袭                                                                           Time Limit: 2000/1000 ...

  9. AC自动机:多模式串匹配实现敏感词过滤

    文章出处:极客时间<数据结构和算法之美>-作者:王争.该系列文章是本人的学习笔记. 1 敏感词过滤场景 在很多支持用户发表内容的网站,都有敏感词过滤替换的功能.例如将一些淫秽.反动内容过滤 ...

最新文章

  1. slot没有毁灭的问题_解析flink之perjob模式下yn参数不生效问题
  2. window系统查看端口被哪个进程占用了
  3. python 栈和队列_Python实现栈和队列的简单操作方法示例
  4. [性能] SAP销售订单取数逻辑优化---索引表
  5. Serverless的理解
  6. OpenCASCADE:建模算法之隐藏线去除
  7. Linux vim使用心得--一些高级话题
  8. 分布式部署_Apache Spark探秘:三种分布式部署方式比较
  9. 在Java中调用祖父母方法:您不能
  10. 远程Linux主机安装Oh My Zsh
  11. 【电路补习笔记】1、电阻的参数与选型
  12. 2020-3-20前端题目
  13. 【软件测试】软件测试过程模型
  14. 40页PPT,让你了解智能物联网应用场景需求与未来发展趋势
  15. matlab 数据白化,数据白化
  16. 惠普服务器bios修改ilo,HPE Gen10 Plus iLO5 BIOS设置固定IP地址
  17. 《程序员》 -- 《程序员》2013年11月刊: 运维
  18. 湖南大学工训创新大作业——改进电子音乐
  19. 利用公网IP访问部署在阿里云服务器的spring boot项目(一)
  20. 南开大学计算机2019分数线,2019年南开大学录取分数线(预估)

热门文章

  1. ActiveX组件及其注册
  2. 冬日娜刻薄提问雷哭史冬鹏 无厘头堪比韩乔生
  3. 外贸常用英语100句
  4. SLR(1),LALR(1),LR(1)文法的区别
  5. android 软键盘工具类,Android开发之弹出软键盘工具类简单示例
  6. 二叉树的遍历规则(前序遍历、后序遍历、中序遍历)
  7. Linux CentOS 平台安装 JDK 的三种方法
  8. Android逆向 学习Android安全和逆向开发的路线总结,啃下这些Framework技术笔记
  9. 013A-生成树STP概念
  10. 表格实现excel导出功能