这题说的是 有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. 查找->静态查找表->次优查找(静态树表)

    文字描算 之前分析顺序查找和折半查找的算法性能都是在“等概率”的前提下进行的,但是如果有序表中各记录的查找概率不等呢?换句话说,概率不等的情况下,描述查找过程的判定树为何类二叉树,其查找性能最佳? 如 ...

  2. python time模块总结

    常用函数: import time --------------------------------------------------time.time()                      ...

  3. 【Python全栈-JavaScript】JavaScript入门

    JavaScript基础知识点 一.JavaScript概述 参考:http://www.w3school.com.cn/b.asp JavaScript的历史 1.1992年Nombas开发出C-m ...

  4. 封装 vue 组件的过程

    首先,组件可以提升整个项目的开发效率.能够把页面抽象成多个相对独立的模块,解决了我们传统项目开发的缺点:效率低,难维护,复用性等问题: 然后,使用Vue.extend方法创建一个组件,然后使用 Vue ...

  5. dedecms调用全站相关文章怎么设置

    前面我们说了dedecms调用相关文章,但很多网友反映说调用的只是本栏目的相关文章,不是全站的相关文章,那么dedecms调用全站相关文章怎么设置呢?打开文件\include\taglib\likea ...

  6. 20180824 SSRS Line Chart 绘制

    (很多时候我都会只记录遇到的问题点,很少详细的写整个过程) 1. 安装ReportBulider 客户端,不需要填写server url ,可以先放空,后面再维护. 安装包官网可以下载,是免费的,现在 ...

  7. MySQL8.0.11 组复制配置

     my.cnf [mysql] prompt='node2 [\h] {\u} (\d) > ' # [client] user = sa password = cc.123 port = 22 ...

  8. jmeter报错:响应数据HTTP Status 500 & 后台日志Typed variable declaration : Object constructor

    今天在测试文件下载接口,发现在测试单个文件下载1次时,文件成功下载.但是在测试单个文件并发下载50次时,Jmeter报错了,后台服务器tomcat竟然没有发现报错信息. Jmeter响应信息报错: H ...

  9. 自定义安装visual studio 2010开发asp.net

    VS2010的安装对于VS的安装大家肯定都熟悉,不过我在很多地方看到的是大家讲VS的全部组件都安装了,不但浪费磁盘空间,还降低了系统性能,除此之外,还有人安装了VS之后不知道顺手把MSDN安装上,害得 ...

  10. RN-TextInput组件去掉下划线

    <View style={styles.container}> <TextInput style={styles.textInputStyle} underlineColorAndr ...