String Set Queries

题意:给你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自动机的更多相关文章

  1. [hdu2222] [AC自动机模板] Keywords Search [AC自动机]

    AC自动机模板,注意!ch,Fail,lab数组的大小不是n而是节点个数,需要认真计算! #include <iostream> #include <algorithm> #i ...

  2. 【优化AC】建立联系

    建立联系 [试题描述] 新学期开始了,不料同学们在假期集体更换了电话,所以同学们只能重新建立联系. 班内一共有n位同学,他们一共建立了m次联系,老师想知道在同学们每次建立完一个联系后,一共有多少对同学 ...

  3. AC日记——手写堆ac合并果子(傻子)

    今天整理最近的考试题 发现一个东西叫做优先队列 priority_queue(说白了就是大根堆) 但是 我对堆的了解还是很少的 所以 我决定手写一个堆 于是我写了一个简单的堆 手写的堆说白了就是个二叉 ...

  4. 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 ...

  5. bzoj 3796: Mushroom追妹纸 AC自动机+后缀自动机+dp

    题目大意: 给定三个字符串s1,s2,s3,求一个字符串w满足: w是s1的子串 w是s2的子串 s3不是w的子串 w的长度应尽可能大 题解: 首先我们可以用AC自动机找出s3在s1,s2中出现的位置 ...

  6. HDU4787 GRE Words Revenge(AC自动机 分块 合并)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4787 Description Now Coach Pang is preparing for ...

  7. poj 2278 DNASequnce AC自动机

    地址:http://poj.org/problem?id=2778 题目: DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Total S ...

  8. [知识点]Trie树和AC自动机

    // 此博文为迁移而来,写于2015年5月27日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w1s8.html 1.前 ...

  9. HDU-4534 郑厂长系列故事——新闻净化 AC自动机+DP

    题意:给定一些单词,这些单词必须要是一个目标串的子串,同时给定一些串,这些串不能够出现在目标串中,其余一些串只会带来不同附加值.现在问满足前两者的情况下,要求附加值最大.数据给定一个原始串,现在要求在 ...

随机推荐

  1. Nginx 的简单使用 (IIS,Asp.Net)

    Nginx 的一些常见功能(windows,AspNet ,IIS) 下载 官方网站:https://nginx.org/en/download.html 下载,解压缩是这个样子 启动: 启动方式有两 ...

  2. 【Android】Theme.AppCompat.Light 问题

    Android 开发的 styles.xml 文件中遇到了这个问题: <style name="AppBaseTheme" parent="Theme.AppCom ...

  3. 【iOS】iOS 调试快速定位程序在哪崩溃

    iOS 开发过程中经常遇到程序崩溃.快速定位程序在哪崩溃的步骤如下: 1. 2. 3. 这样设置后,程序崩溃时会定位到崩溃的语句,如下: 原文链接:iOS开发何如在调试的时候轻松找到程序在哪里崩溃

  4. Scala的常用小技巧

    1."RichString.java".stripSuffix(".java") == "RichString" "http:// ...

  5. 内容汇总(c语言)

    一,内容 常量(整型,浮点型,字符型,字符串型,符号常量) 变量(基本类型:整形,浮点型,字符型,枚举型:构造类型:数组,结构体,共用体:另外还有指针类型和NULL) 顺序结构 分支结构 循环结构 当 ...

  6. RGW 学习 前言

    对于CEPH的学习已经有一段的时间了,最近的一段时间都是集中在RGW网关这一方面,所以准备将学习的过程以及源代码的分析,将以随笔的形式记录下来. 每天更新一章.

  7. LeetCode :2.两数相加 解题报告及算法优化思路

    题目连接:2.两数相加 题意 题目难度标为 中等, 因为题意上有一部分理解难度,以及需要数据结构的链表基础. 还不知道到链表的童鞋可以粗略的看下百度百科或者是翻出数据结构的书看一看,通俗一点的语言来解 ...

  8. 修改 jupyter notebook的默认文件夹位置

    安装好Anaconda 3以后,就可以使用Jupyter notebook了,但是我们打开Jupyter notebook后,发现界面是一个默认的目录,这个目录在哪里?如果想把自己写的程序文件保存在自 ...

  9. 【0729 | Day 3】Python基础(一)

    Part 1 变量 一.什么是变量? 字面意思:变化的量. 而在计算机中,我们可以将它理解为世间万物变化的状态. 二.为什么要有变量? 首先,无论是我们还是计算机都需要变量来记录发生的状态的变化,其次 ...

  10. Source Maps简介

    提高网站性能最简单的方式之一是合并压缩JavaScript和CSS文件.但是当你需要调试这些压缩文件中的代码时,那将会是一场噩梦.不过也不用担心,souce maps将会帮你解决这一问题. Sourc ...