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
题意:给定一些单词,这些单词必须要是一个目标串的子串,同时给定一些串,这些串不能够出现在目标串中,其余一些串只会带来不同附加值.现在问满足前两者的情况下,要求附加值最大.数据给定一个原始串,现在要求在 ...
随机推荐
- StarUML 3.0 破解方法
首先在我这里下载 StarUML3.0 破解替换文件app.asar 链接:https://pan.baidu.com/s/1wDMKDQkKrE9D1c0YeXz0xg 密码:y65m 然后参照下 ...
- Hyper-V虚拟机上安装Ubuntu16.04/Ubuntu18.04.2LTS,搭建GitLab
我的电脑系统是win10,内存8g如下 一开始是装的Ubuntu18.04.2LTS, gitlab-ce_12.1.3-ce.0_amd64.deb,每次能够安装成功,但是修改完ip后,运行gitl ...
- 【算法】【排序】【插入类】希尔排序 ShellSort
#include<stdio.h> #include <time.h> #include<stdlib.h> int main(){ ]; //设立随机数 sran ...
- 前后端分离后台api接口框架探索
前言 很久没写文章了,今天有时间,把自己一直以来想说的,写出来,算是一种总结吧! 这篇文章主要说前后端分离模式下(也包括app开发),自己对后台框架和与前端交互的一些理解和看法. 前后端分离 ...
- API开发之接口安全(三)----sign有效时间
之前生成的sign和校验sign我们已经完全掌握了.但是仅仅凭借这样的sign是无法满足我们的需求的,如果一个黑客通过抓包抓到你的数据 他可以去修改你的header为这样的 body为那样的 也是可以 ...
- windows如何访问wsl系统下的文件
windows如何访问wsl系统下的文件 可以在wsl终端输入以下命令 explorer.exe . 会出现如下界面 这样就可以很方便的查看wsl的文件了
- ORACLE中添加删除主键
本文转自:http://blog.chinaunix.net/uid-17079336-id-2832443.html 1.创建表的同时创建主键约束(1)无命名create table student ...
- OpenResty 社区王院生:APISIX 的高性能实践
2019 年 7 月 6 日,OpenResty 社区联合又拍云,举办 OpenResty × Open Talk 全国巡回沙龙·上海站,OpenResty 软件基金会联合创始人王院生在活动上做了&l ...
- Linux的crond和crontab
一.crond cron是一个linux下的定时执行工具(相当于windows下的scheduled task),可以在无需人工干预的情况下定时地运行任务task. 由于cron 是Linux的ser ...
- 建立apk定时自动打包系统第二篇——自动上传文件
在<建立apk定时自动打包系统第一篇——Ant多渠道打包并指定打包目录和打包日期>这篇文章中介绍多渠道打包的流程.很多时候我们需要将打包好的apk上传到ftp中,这时候我可以修改custo ...