这题说的是 有n次操作 +w 表示读入一个字符串,?p 询问这个字符串的子串在那些模板串中有多少个,

http://blog.csdn.net/qq574857122/article/details/16826631

就是说先存一部分的字符串,因为每次都要进行重新 建立这个失配指针,也就是说让适当的单词进行失配 指针重建 会达到高效,两个ac自动机,选取sqrt(100000)的时候达到相对优一点,这样我们 当第一棵树超过了 800的时候我们就将第一棵树的东西存入第二棵树这样我们可以相对减少对失配指针的重建

#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
#include <cstdio>
using namespace std;
const int maxn=;
struct Aho{
int ch[maxn][];
int f[maxn];
bool val[maxn];
int last[maxn];
int sz;
void init()
{
sz=;
ch[][]=ch[][]=;val[]=;last[]=;
}
int idx(char c){
return c==''?:;
}
void insert(char *s,int n)
{
int u=;
for(int i=; i<n; i++)
{
int c=idx(s[i]);
if(ch[u][c]==)
{
ch[sz][]=ch[sz][]=;
val[sz]=;
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]=true;
}
bool search(char *s,int n)
{
int u=;
for(int i=; i<n; i++)
{
int c=idx(s[i]);
if(ch[u][c]==)return false;
u=ch[u][c];
}
return val[u];
}
int print(int j)
{
int ans=;
while(j)
{
ans++;j=last[j];
}
return ans;
}
int find(char *T,int n)
{
int j=;
int ans=;
for(int i=; i<n; i++)
{
int c=idx(T[i]);
while(j&&ch[j][c]==)j=f[j];
j=ch[j][c];
if(val[j])ans+=print(j);
else if(last[j])ans+=print(last[j]);
}
return ans;
}
void getFail()
{
queue<int>q;
last[]=f[]=;
for(int c=; c<; c++)
{
int u=ch[][c];
if(u){q.push(u);f[u]=last[u]=;}
}
while(!q.empty())
{
int r = q.front();
q.pop();
for(int c=; c<; c++)
{
int u=ch[r][c];
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,buf;
char s[],temp[];
void dfs(int u,int v)
{
queue<int>U,V;
U.push();V.push();
while(!U.empty())
{
u=U.front();U.pop();
v=V.front();V.pop();
for(int i=;i<; i++)
if(buf.ch[v][i])
{
int e2=buf.ch[v][i];
if(ac.ch[u][i]==)
{
ac.ch[ac.sz][]=ac.ch[ac.sz][]=;
ac.val[ac.sz]=;
ac.ch[u][i]=ac.sz++;
}
int e1=ac.ch[u][i];
ac.val[e1]|=buf.val[e2];
U.push(e1);V.push(e2);
}
}
}
void join()
{
dfs(,);
buf.init();
ac.getFail();
}
int main()
{
int cas;
scanf("%d",&cas);
for(int cc=; cc<=cas ; cc++)
{
int n;
scanf("%d",&n);
ac.init();
buf.init();
int L=;
printf("Case #%d:\n",cc);
for(int i=;i<n; i++)
{
scanf("%s",temp);
int len=strlen(temp+);
s[]=temp[];
for(int i=; i<len; i++)
s[i+]=temp[+((i+L)%len)];
if(s[]=='+')
{
if(buf.search(s+,len)||
ac.search(s+,len))continue;
buf.insert(s+,len);
buf.getFail();
if(buf.sz>)join();
}else
{
L=buf.find(s+,len)+ac.find(s+,len);
printf("%d\n",L);
}
}
}
return ;
}

hdu4787 AC自动机加分块的更多相关文章

  1. [POJ2778]DNA Sequence(AC自动机 + DP + 矩阵优化)

    传送门 AC自动机加DP就不说了 注意到 m <= 10,所以模式串很少. 而 n 很大就需要 log 的算法,很容易想到矩阵. 但是该怎么构建? 还是矩阵 A(i,j) = ∑A(i,k) * ...

  2. HDU4787 GRE Words Revenge【AC自动机 分块】

    HDU4787 GRE Words Revenge 题意: \(N\)次操作,每次记录一个\(01\)串或者查询一个\(01\)串能匹配多少个记录的串,强制在线 题解: 在线的AC自动机,利用分块来降 ...

  3. HDU4787 GRE Words Revenge(AC自动机 分块 合并)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4787 Description Now Coach Pang is preparing for ...

  4. [CF587F]Duff is Mad[AC自动机+根号分治+分块]

    题意 给你 \(n\) 个串 \(s_{1\cdots n}\) ,每次询问给出 \(l,r,k\) ,问在 \(s_{l\cdots r}\) 中出现了多少次 \(s_k\) . \(n,q,\su ...

  5. 【CF587F】Duff is Mad AC自动机+分块

    [CF587F]Duff is Mad 题意:给出n个串$s_1,s_2..s_n$,有q组询问,每次给出l,r,k,问你编号在[l,r]中的所有串在$s_k$中出现了多少次. $\sum|s_i|, ...

  6. CodeForces - 710F:String Set Queries (二进制分组 处理 在线AC自动机)

    ou should process m queries over a set D of strings. Each query is one of three kinds: Add a string ...

  7. (17/34)AC自动机/后缀数组/后缀自动机(施工中)

    快补题别再摸鱼了(17/34) 1.AC自动机 #define maxnode 1000010 #define maxsize 26 struct ahocT{ int ch[maxnode][max ...

  8. CF587F-Duff is Mad【AC自动机,根号分治】

    正题 题目链接:https://www.luogu.com.cn/problem/CF587F 题目大意 给出\(n\)个字符串\(s\).\(q\)次询问给出\(l,r,k\)要求输出\(s_{l. ...

  9. BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2545  Solved: 1419[Submit][Sta ...

随机推荐

  1. webpack4入门配置

    下面是抄过来的,方便自己翻越 webpack4.x入门配置   1.首先npm install webpack webpack-cli webpack-dev-server -g (mac电脑用超级管 ...

  2. 重读《深入理解Java虚拟机》一、Java虚拟机内存区域的划分

    一.Java虚拟机内存区域如何划分 1.Java虚拟机内存区域的划分 区域名称 作用(用途) 类型 特点 虚拟机规定异常情况 内存分配与回收 其他说明 1 程序计数器 指示当前正在执行的字节码指令地址 ...

  3. 终于解决“Git Windows客户端保存用户名与密码”的问题(转载)

    add by zhj:不建议用这种方法,建议用SSH,参见 TortoiseGit密钥的配置 http://www.cnblogs.com/ajianbeyourself/p/3817364.html ...

  4. logback 常用配置详解(序)logback 简介

    转自:http://aub.iteye.com/blog/1101260 logback 简介 Ceki Gülcü在Java日志领域世界知名.他创造了Log4J ,这个最早的Java日志框架即便在J ...

  5. 数据重组:对一堆相似字典进行分类统计(shidebin)

    数据重组 # 需求说明:将data_source分类统计,并输出为如下data_final的形式: # data_final ===> # { # 'area': [{'place': '南山区 ...

  6. 前端 HTML form表单标签 input标签 type属性 radio 单选框

    <input type="radio"> 单选框 适用于 选择性别按钮网页等 <!DOCTYPE html> <html lang="en& ...

  7. 数据库---mysql的介绍和安装

    MySQL数据库 一.简介: mysql是数据库管理软件:套接字:服务端,客户端 支持并发:操作得是共享得数据 处理锁,数据安全,性能 用别人得软件,得照着别人得规范,组织自己得语法规则 二.概述: ...

  8. Python--共享变量

    - 共享变量: 当多个线程同时访问一个变量的时候,会产生共享变量的问题 - 案例11 - 解决变量:锁.信号灯 - 锁(Lock): - 是一个标志,表示一个线程在占用一些资源 - 使用方法 - 上锁 ...

  9. 云锁-安全,易用,灵活的许可-Virbox许可管理平台

    云许可,助力开发者保护软件财富 Virbox 云锁提供高强度加密及软件许可管理功能 安全,易用,灵活 防破解 云许可安全性体验与硬件锁一致,避免盗版导致损失 加密保护技术:反黑引擎/碎片代码执行/虚拟 ...

  10. java poi生成excel(个人例子js-jsp-java)

    js代码: function exportRepQudl(){ if(confirm("导出输出页面内容?")){ var id = $("input[name='id' ...