这题说的是 有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. 《Redis 集群》

    由于集群这章节内容较多,也比较重要,所以单独拉出来,做一个小章节. 1:如何搭建一个集群? - 环境为 Ubuntu16.04 - 这里我预计使用 9001 - 9006 端口,生成一个 6 台机器的 ...

  2. oracle序列的增、删、改、查及使用

    ----------------------------------------------------------------------创建序列:示例:CREATE SEQUENCE SEQ_SS ...

  3. 【PyQt5-Qt Designer】鼠标+键盘事件

    重定义鼠标响应+键盘响应事件 一,每个事件都被封装成相应的类: pyqt中,每个事件类型都被封装成相应的事件类,如鼠标事件为QMouseEvent,键盘事件为QKeyEvent等.而它们的基类是QEv ...

  4. SQL Server 2008 R2提示评估期已过

    解决SQL Server 2008 r2提示评估期已过 1.注册表把 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\100\Co ...

  5. oracle表空间的管理

    1.创建表空间 CREATE TABLESPACE TBS_TR_DATA DATAFILE '/oradata/rTBS_TR_DATA_001.dbf' SIZE 64G EXTENT MANAG ...

  6. mysql 查询优化杂谈

    一.把某些判断移动到应用层 我们需要在一张表里面删除某种类型的数据,大概的表结构类似这样: CREATE TABLE t ( id INT, tp ENUM ("t1", &quo ...

  7. 集成xxl-job分布式任务调度平台

    首先声明,本篇博文基于springboot,基于spring的请自行研究. (一)启动控制平台 首先将xxl-job-master.zip下载下来,然后在mysql数据库创建xxl-job数据库. 执 ...

  8. 前端 chrome查看html样式基本操作

    Chrome浏览器是世界上HTML5支持最好的浏览器.提供了非常好的开发工具,非常适合我们开发人员使用.审查元素功能的快捷键是F12. 按检查或者F12 鼠标点击找标签 chorme审查元素的使用 - ...

  9. what's the python之if判断、while循环以及for循环

    Python缩进原则 顶级代码必须顶行写,即如果一行代码本身不依赖于任何条件,那它必须不能进行任何缩进 同一级别的代码,缩进必须一致 官方建议缩进用4个空格 Python程序语言指定任何非0和非空的布 ...

  10. 亚马逊IOT-SDK,线程池数

    1111