这题说的是 有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. DbGridEh中改变行的颜色

    DbGridEh中改变行的颜色 代码也挺简单的,只是当时没有想到: if ds2.FieldByName('AutoRead').AsInteger=0 thenbegin  DBGridEh1.Ca ...

  2. SQL instr()函数的格式

    格式一:instr( string1, string2 )    /   instr(源字符串, 目标字符串) 格式二:instr( string1, string2 [, start_positio ...

  3. disruptor的并行用法

    实现EventFactory,在newInstance方法中返回,ringBuffer缓冲区中的对象实例:代码如下: public class DTaskFactory implements Even ...

  4. mysql数据库的备份和还原

    mysql数据库的备份命令:mysqldump -u root  -p 要备份的现有数据库名  >  备份后的sql文件名.sql,例如:  mysqldump -u root -p  heal ...

  5. BZOJ4391 High Card Low Card [Usaco2015 dec](贪心+线段树/set库

    正解:贪心+线段树/set库 解题报告: 算辣直接甩链接qwq 恩这题就贪心?从前往后从后往前各推一次然后找一遍哪个地方最大就欧克了,正确性很容易证明 (这里有个,很妙的想法,就是,从后往前推从前往后 ...

  6. C# Asp.net使用FormData对象实现ajax提交表单及上传图片

    1.html代码: <form id="postForm"> 文件名:<input type="text" name="filena ...

  7. mysql mpm

    mysql mpm 参考文章 http://www.myexception.cn/mysql/1968274.html http://www.linuxidc.com/Linux/2013-07/86 ...

  8. mysql在linux上的安装

    前提: 环境:workstation 11 + CentOS 7 + mysql-5.6.40 安装前先查看服务器里是否有老版本的mysql已经被安装了 rpm -qa|grep mysql 如果有就 ...

  9. FastReport快速安装教程

    安装后需要覆盖的文件全部复制到安装目录 替换后的安装目录 选中Recompile右键必须以管理员运行 看图选择 编译后,需要汉化的话看下图选择 怎么添加Library直接看图按顺序进行 选择insta ...

  10. Windows 7中200M神秘隐藏分区

    裸机全新安装Windows 7的用户,在安装完成后运行diskmgmt.msc打开磁盘管理器,可以看到在系统分区(一般为C分区)之前有一个大小为200MB的隐藏分区.这个特殊的隐藏分区与Windows ...