hdu4787 AC自动机加分块
这题说的是 有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自动机加分块的更多相关文章
- [POJ2778]DNA Sequence(AC自动机 + DP + 矩阵优化)
传送门 AC自动机加DP就不说了 注意到 m <= 10,所以模式串很少. 而 n 很大就需要 log 的算法,很容易想到矩阵. 但是该怎么构建? 还是矩阵 A(i,j) = ∑A(i,k) * ...
- HDU4787 GRE Words Revenge【AC自动机 分块】
HDU4787 GRE Words Revenge 题意: \(N\)次操作,每次记录一个\(01\)串或者查询一个\(01\)串能匹配多少个记录的串,强制在线 题解: 在线的AC自动机,利用分块来降 ...
- HDU4787 GRE Words Revenge(AC自动机 分块 合并)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4787 Description Now Coach Pang is preparing for ...
- [CF587F]Duff is Mad[AC自动机+根号分治+分块]
题意 给你 \(n\) 个串 \(s_{1\cdots n}\) ,每次询问给出 \(l,r,k\) ,问在 \(s_{l\cdots r}\) 中出现了多少次 \(s_k\) . \(n,q,\su ...
- 【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|, ...
- 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 ...
- (17/34)AC自动机/后缀数组/后缀自动机(施工中)
快补题别再摸鱼了(17/34) 1.AC自动机 #define maxnode 1000010 #define maxsize 26 struct ahocT{ int ch[maxnode][max ...
- CF587F-Duff is Mad【AC自动机,根号分治】
正题 题目链接:https://www.luogu.com.cn/problem/CF587F 题目大意 给出\(n\)个字符串\(s\).\(q\)次询问给出\(l,r,k\)要求输出\(s_{l. ...
- BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2545 Solved: 1419[Submit][Sta ...
随机推荐
- 第三方python 加密库 --- cryptography
1,安装依赖 pip install cryptography 2,生成秘钥 from cryptography.fernet import Fernet #秘钥#随机生成秘钥 cipher_key ...
- Anaconda 虚拟环境安装及应用
首先要安装Anaconda 下载网址:https://www.anaconda.com/distribution/#download-section Miniconda下载网址:https: ...
- NOIP观光公交
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #inc ...
- oracle稳定执行计划(更改)的方法
应用于那些执行计划已经发生了的不好的变更的SQL上(在不改变SQL文本的情况下,改变其执行计划),即便通过创建SQL Profile解决了目标SQL执行计划变更的问题,依然不能保证系统后续执行的SQL ...
- (4.2)mysql备份还原——备份概述
1.什么情况下会用到备份呢? [1.1]灾难恢复 [1.2]单位审计:数据库在过去某一个点是什么样的 [1.3]跨机房灾备:异地备份 [1.4]认为的DDL或者DML语句,导致主从库的数据消失 [1. ...
- 使用SQL Server 的CDC功能实现数据变更捕获
USE t; GO --开启某个数据库的CDC功能 exec sys.sp_cdc_enable_db GO --is_cdc_enabled栏位为1代表开启CDC功能了 SELECT is_cdc_ ...
- 由swap引发的关于按值传递和引用传递的思考与总结
函数的参数传递定义:在调用一个函数时,将实参传递给形参. C++中函数的参数传递有按值传递.地址传递和引用传递3种方式.注意:地址也是一种值,按值传递和按地址传递都是单向的值传递方式,即形参都不会回传 ...
- abap特性
1:实例成员是属于某一个对象的,静态成员属于整个类. 2:abap类中,可以定义三种不同类型的成员,分布是属性(如data),方法(method),事件(event). 3: abap中定义静态属性的 ...
- 【Python】-NO.99.Note.4.Python -【Python3 条件语句 循环语句】
1.0.0 Summary Tittle:[Python]-NO.99.Note.4.Python -[Python3 条件语句 循环语句] Style:Python Series:Python Si ...
- Centos7系统防火墙上开端口
//permanent 永久生效 没有此参数重启失效 firewall -cmd --zone=public --add -port=80/tcp --permanent //开 ...