CF710F String Set Queries

支持字符串的插入和删除。。。SAM也干不了这个事

所以可以用cdq分治+AC自动机O(nlogn)解决

但是本题强制在线~~~

我们还有一个工具,叫做二进制分组!

所以,每组建立一个AC自动机,合并的时候,AC自动机合并。最后再build失配指针

随机删除?虽然不是栈序删除了,但是,统计数量具有贡献独立性,再对删除串建立一个AC自动机集群即可!

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
char ch;x=;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
namespace Miracle{
const int N=3e5+;
int m;
int ch[N][];
int vis[N][];
int fail[N],num[N],tot[N];
int rt[N],sz[N];
int cnt,totid;
struct AC{
int sta[N],top;
int merge(int x,int y){
// cout<<"merge "<<x<<" "<<y<<endl;
if(!x||!y) return x+y;
for(reg i=;i<;++i) ch[x][i]=merge(ch[x][i],ch[y][i]);
num[x]+=num[y];
return x;
}
void build(int id){
queue<int>q;
for(reg i=;i<;++i){
if(ch[rt[id]][i]) fail[vis[rt[id]][i]=ch[rt[id]][i]]=rt[id],q.push(vis[rt[id]][i]);
else vis[rt[id]][i]=rt[id];
}
while(!q.empty()){
int x=q.front();q.pop();
tot[x]=num[x]+tot[fail[x]];
for(reg i=;i<;++i){
if(ch[x][i]){
fail[vis[x][i]=ch[x][i]]=vis[fail[x]][i];
q.push(vis[x][i]);
}else{
vis[x][i]=vis[fail[x]][i];
}
}
}
}
int query(char *s){
int len=strlen(s+);
int ret=;
for(reg i=;i<=top;++i){
int id=sta[i];
int now=rt[id];
for(reg i=;i<=len;++i){
now=vis[now][s[i]-'a'];
ret+=tot[now];
}
}
return ret;
}
void ins(char *s){
int id=++totid;
int len=strlen(s+);
if(!rt[id]) rt[id]=++cnt;
int now=rt[id];
for(reg i=;i<=len;++i){
int x=s[i]-'a';
ch[now][x]=++cnt;
now=ch[now][x];
}
++num[now];
//dfs(rt[id]);
// cout<<rt[id]<<" "<<cnt<<endl;
sz[id]=;
// cout<<" after ins "<<id<<endl;
while(top&&sz[sta[top]]==sz[id]) rt[id]=merge(rt[id],rt[sta[top]]),sz[id]+=sz[sta[top]],--top;
// cout<<" after merge "<<endl;
build(id);
sta[++top]=id; }
}f,d;
char s[N];
int main(){
rd(m);
int op;
for(reg i=;i<=m;++i){
rd(op);scanf("%s",s+);
if(op==)f.ins(s);
else if(op==)d.ins(s);
else {
printf("%d\n",f.query(s)-d.query(s));
}
fflush(stdout);
}
return ;
} }
signed main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
Date: 2019/2/24 15:19:38
*/

二进制分组,对于许多插入删除根本不虚,反正暴力重构删除,O(nlogn)

(当然如果贡献不独立,还是cdq或者线段树分治吧,,)

最新文章

  1. 编程模式之模板方法模式(Template Method)
  2. XCAT在虚拟机上部署系统
  3. 爬虫:获取多次跳转后的页面url
  4. sh脚本执行Java程序
  5. Arcengine10下载地址
  6. -_-#Error
  7. FineUI上传控件
  8. WebWorker SharedWorker ServiceWorker
  9. JS控制语句(if、for等)、数组(例题)、方法(常用方法介绍)
  10. 初识大数据(二. Hadoop是什么)
  11. assets 与 res 目录的区别
  12. ThinkingInJava 学习 之 0000004 初始化与清理
  13. Linux 第一周作业
  14. VS2015 添加web服务(电子看板)
  15. Codeforces Round #397 by Kaspersky Lab and Barcelona Bootcamp (Div. 1 + Div. 2 combined) D. Artsem and Saunders 数学 构造
  16. Netty4.0学习笔记系列之二:Handler的执行顺序
  17. 安装完xampp启用时,计算机中丢失api-ms-win-crt-conio-l1-1-0.dll怎么办?
  18. 在windows中安装两个不同版本的Python
  19. imx6 spi分析
  20. org.springframework.orm.hibernate3.HibernateTemplate

热门文章

  1. springboot @Value 获取计算机中绝对路径文件的内容
  2. 使用canvas实现一个圆球的触壁反弹
  3. 《坦克世界》1.0+:使用 CPU 优化的图形和物理丰富用户体验
  4. 阿里云Https通配符证书购买
  5. systemctl添加开机启动
  6. “北航学堂”M2阶段postmortem
  7. Natural Language Generation/Abstractive Summarization
  8. Linux内核分析——第十八章 调试
  9. 最新广商小助手 项目进展 OpenGL ES 3D在我项目中引用 代码太多只好选重要部分出来
  10. Hibernate_HQL