AC自动机 建立nlogn个AC自动机
题意:给你3种操作,1、加入一个串到集合中。 2、删除集合中的某一个串 3、查询集合中的字符串在给定的字符串种出现几次。(同一个串可重复)
解法:建立多个AC自动机,用二进制分组来处理。
加入给你21个串: 分为 16+4+1,再添加一个串的时候,即21+1, 22 = 16+4+1+1 = 16 + 4 + 2。 这样每次加串之后只会有logn个操作,查询也变成logn操作, 对于同一个串建立fair指针的次数就少了。
代码:
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 3e5 + ;
struct Node{
static const int m = ;static const int KN = N;
int next[KN][m], fair[KN], tot = , mark[KN], mark1[KN], root[], cnt = , si[];
void Build(int x){
queue<int> q;
q.push(x);
int pos, p, v;
while(!q.empty()){
pos = q.front(), q.pop();
for(int i = ; i < m; i++){
if(!next[pos][i]) continue;
p = fair[pos]; v = next[pos][i];
while(p && !next[p][i]) p = fair[p];
if(p) fair[v] = next[p][i];
else fair[v] = x;
q.push(v);
mark1[v] = mark1[fair[v]] + mark[v];
}
}
}
void Add(char s[], char ch){
root[++cnt] = ++tot; si[cnt] = ;
int pos = root[cnt];
for(int i = ; s[i]; i++){
if(!next[pos][s[i]-ch]) next[pos][s[i]-ch] = ++tot;
pos = next[pos][s[i]-ch];
}
mark[pos]++;
while(si[cnt] == si[cnt-]){
Unit(root[cnt-], root[cnt]);
si[--cnt] *= ;
}
Build(root[cnt]);
}
int Query(char s[], char ch){
int pos, ret = ;
for(int id = ; id <= cnt; id++){
pos = root[id];
for(int i = ; s[i]; i++){
while(pos && !next[pos][s[i]-ch]) pos = fair[pos];
if(pos) pos = next[pos][s[i]-ch];
else pos = root[id];
ret += mark1[pos];
}
}
return ret;
}
void Unit(int u, int v){
mark[u] += mark[v];
for(int i = ; i < m; i++){
if(!next[u][i] || !next[v][i]) next[u][i] += next[v][i];
else Unit(next[u][i], next[v][i]);
}
}
}ac[];
char str[N];
int main(){
int n, k;
scanf("%d", &n);
while(n--){
scanf("%d%s", &k, str);
if(k <= ) ac[k-].Add(str, 'a');
else {
printf("%d\n", ac[].Query(str, 'a')-ac[].Query(str, 'a'));
fflush(stdout);
}
}
return ;
}
AC自动机
AC自动机 建立nlogn个AC自动机的更多相关文章
- [hdu2222] [AC自动机模板] Keywords Search [AC自动机]
AC自动机模板,注意!ch,Fail,lab数组的大小不是n而是节点个数,需要认真计算! #include <iostream> #include <algorithm> #i ...
- 【优化AC】建立联系
建立联系 [试题描述] 新学期开始了,不料同学们在假期集体更换了电话,所以同学们只能重新建立联系. 班内一共有n位同学,他们一共建立了m次联系,老师想知道在同学们每次建立完一个联系后,一共有多少对同学 ...
- AC日记——手写堆ac合并果子(傻子)
今天整理最近的考试题 发现一个东西叫做优先队列 priority_queue(说白了就是大根堆) 但是 我对堆的了解还是很少的 所以 我决定手写一个堆 于是我写了一个简单的堆 手写的堆说白了就是个二叉 ...
- 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 ...
- bzoj 3796: Mushroom追妹纸 AC自动机+后缀自动机+dp
题目大意: 给定三个字符串s1,s2,s3,求一个字符串w满足: w是s1的子串 w是s2的子串 s3不是w的子串 w的长度应尽可能大 题解: 首先我们可以用AC自动机找出s3在s1,s2中出现的位置 ...
- HDU4787 GRE Words Revenge(AC自动机 分块 合并)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4787 Description Now Coach Pang is preparing for ...
- poj 2278 DNASequnce AC自动机
地址:http://poj.org/problem?id=2778 题目: DNA Sequence Time Limit: 1000MS Memory Limit: 65536K Total S ...
- [知识点]Trie树和AC自动机
// 此博文为迁移而来,写于2015年5月27日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w1s8.html 1.前 ...
- HDU-4534 郑厂长系列故事——新闻净化 AC自动机+DP
题意:给定一些单词,这些单词必须要是一个目标串的子串,同时给定一些串,这些串不能够出现在目标串中,其余一些串只会带来不同附加值.现在问满足前两者的情况下,要求附加值最大.数据给定一个原始串,现在要求在 ...
随机推荐
- 【Java】Class JavaLaunchHelper is implemented in both ** and **
详细问题描述如下: objc[64179]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachin ...
- 坐标下降法(coordinate descent method)求解LASSO的推导
坐标下降法(coordinate descent method)求解LASSO推导 LASSO在尖点是singular的,因此传统的梯度下降法.牛顿法等无法使用.常用的求解算法有最小角回归法.coor ...
- 配置VNC并远程控制服务器(电脑)
先象征性介绍一下: VNC (Virtual Network Console)是虚拟网络控制台的缩写, 它是一款基于 UNIX 和 Linux 操作系统的优秀.免费.开源的远程控制工具软件. 然后开始 ...
- HBase MapReduce 一些 ClassNotFoundException 所缺少的jar包
我们在用 java 操作 HBase 时,可能会出现相关的 ClassNotFoundException 等异常信息,但是我们又不想把 HBase lib 下的所有jar包全部导入到工程,因为会有 ...
- 基于Starling的mask实现
作为一个从c++转过来的程序员,flash原生的自定义mask实在是太好用,能方便实现各种效果,比如新手引导的高亮.viewport效果等.可惜starling的显示对象并不支持mask特性,查阅go ...
- 转载 | float 清除浮动的7种方法
什么叫浮动:浮动会使当前标签脱离文档流,产生上浮的效果,同时还会影响周边元素(前后标签)及父级元素的位置和width,height属性.下面用一个小例子来看一看浮动的全过程:1.首先我们新建一个网页, ...
- hdu1241 油田计数
具体思路:求联通块,在"@“的周围进行dfs,使用8个方向向量来代表搜索的方向 贴一下我的主要代码段: int dir[8][2]={{1,1},{-1,-1},{1,-1},{-1,1}, ...
- 使用mybatis实现分页查询示例代码分析
*******************************************分页查询开始*************************************************** ...
- springboot整合websocket高级版
目录 sockjs介绍 产生的原因 环境搭建 springboot整合sockjs 使用场景 聊天室开发 点对点通信 群聊 效果 总结 加入战队 微信公众号 上一章节我们说了websocket的优缺点 ...
- LD_PRELOAD和ld --wrap
前言 LD_PRELOAD和ld --wrap都能实现不修改原始代码,替换指定函数的实现.通常我们会使用这些方法,替换如malloc)()/free().read()/write()等函数,并在替换函 ...