显然,题面明摆着让你写一个可持久化 AC 自动机。

但是从空间来说这是不可能的。

想起做 不强制在线 的可持久化数据结构的一种方法,建立“时光树”,具体来说,假若版本 \(x\) 由版本 \(y\) 更改而来,建边 \(x \to y\)。最后在建出的树上遍历并回答询问。

到此我们只需要一个可以支持加入和撤销的 AC 自动机即可。

考虑维护失配树,具体来说,一个字符串出现的次数等于其所有前缀节点在失配树上的祖先中终止节点数量之和,这是一个点修链查,将其转变为子树修单点查,用树状数组维护即可。

#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
using namespace std;
const int maxn = 1e6+5;
class AC_automaton{
public:
int son[maxn][26],fail[maxn],rt,tot,dfncnt;
vector<int> edge[maxn];//fail 树
vector<int> fa[maxn];//原树上的祖先
int L[maxn],R[maxn],len,now;
void insert(string &s,int pos){
len=s.size(),now=rt;
for(int i=0;i<len;i++){
if(son[now][s[i]-'a']==0) son[now][s[i]-'a']=++tot;
now=son[now][s[i]-'a'];
fa[pos].push_back(now);
}
}
void build(){
queue<int> q;
for(int i=0;i<26;i++) if(son[rt][i]) fail[son[rt][i]]=rt,q.push(son[rt][i]);
while(q.size()>0){
int u=q.front();
q.pop();
for(int i=0;i<26;i++){
if(son[u][i]){
fail[son[u][i]]=son[fail[u]][i];
q.push(son[u][i]);
}
else son[u][i]=son[fail[u]][i];
}
}
for(int i=1;i<=tot;i++){
edge[fail[i]].push_back(i);
}
}
inline void dfs(int u){
L[u]=++dfncnt;
for(int v:edge[u]){
if(!L[v]) dfs(v);
}
R[u]=dfncnt;
}//处理子树信息
}AC;
int tr[maxn];
inline void add(int x,int v){
while(x<=AC.dfncnt) tr[x]+=v,x+=lowbit(x);
}
inline int pre(int x){
int res=0;
while(x>0) res+=tr[x],x-=lowbit(x);
return res;
}
int answer[maxn>>1];
struct Edge{
int v,nxt;
}e[maxn];
int head[maxn>>1],cnt;
void add_edge(int u,int v){
e[++cnt].v=v;
e[cnt].nxt=head[u];
head[u]=cnt;
}
vector<int> Query[maxn>>1];
bitset< 500005 > opt;
inline void dfs(int u){
for(int now:Query[u]){
for(int u:AC.fa[now]){
answer[now]+=pre(AC.L[u]);
}
}
Query[u].clear();
for(int i=head[u];i;i=e[i].nxt){
int now=e[i].v;
if(opt[now]==1){
add(AC.L[AC.fa[now].back()],1);
add(AC.R[AC.fa[now].back()]+1,-1);
}
dfs(now);
if(opt[now]==1){
add(AC.L[AC.fa[now].back()],-1);
add(AC.R[AC.fa[now].back()]+1,1);
}
}
}
inline int found(int u){
return tr[u]==u?u:tr[u]=found(tr[u]);
}
int q;
int main(){
cin>>q;
for(int i=1;i<=q;i++){
tr[i]=i;
int lst,op;
string s;
cin>>op>>lst>>s;
opt[i]=(op==1?1:0);
lst=found(lst);
AC.insert(s,i);
if(opt[i]==1) add_edge(lst,i);
else Query[lst].push_back(i),tr[i]=lst;
}
for(int i=0;i<=q;i++) tr[i]=0;
AC.build();
AC.dfs(AC.rt);
dfs(0);
for(int i=1;i<=q;i++) if(opt[i]==0) cout<<answer[i]<<'\n';
return 0;
}

P8451 题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

  10. JSOI2016R3 瞎BB题解

    题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...

随机推荐

  1. 前端使用 Konva 实现可视化设计器(9)- 另存为SVG

    请大家动动小手,给我一个免费的 Star 吧~ 大家如果发现了 Bug,欢迎来提 Issue 哟~ github源码 gitee源码 示例地址 另存为SVG 这一章增强了另存为的能力,实现" ...

  2. 使用beego/bee热启动gin框架

    目录 1.需要关闭gomod 2.安装 bee 3.再开启gomod 4.启动服务 效果: 1.需要关闭gomod export GO111MODULE=off 2.安装 bee go get -u ...

  3. Triton 源码初步研读

    一.核心接口形态 def jit( fn: Optional[T] = None, *, version=None, do_not_specialize: Optional[Iterable[int] ...

  4. 显示器AVG、DVI、HDMI、DisplayPort、Type-C、雷电接口

    在近十年的发展,显示设备的接口发生了巨大的改变.以前使用比较多的是蓝色VGA接口,接著出现了白色的DVI接口,当遇到不同接口时,还得买转接头进行转接.后来,又有了HDMI等接口,现在则出现DP和USB ...

  5. 关于sql server导出csv格式文件的身份证号乱码问题处理办法

    1.使用SQL Server数据库经常会遇到导出大量数据的情况,例如导出40万条数据,虽然EXCL支持可以放入百万的数据,但是使用数据库复制,粘贴到EXCL表格时,数据库会提示溢出的情况,如下图所示: ...

  6. 基于AIRIOT平台构建低成本、更聪明的智能环卫系统,让管理更加高效智能

    环卫工程作为城市基础设施保障,是城市建设管理中不可或缺的重要组成部分.随着城市进程的加快及技术的进步,环卫工程管理也在逐渐向精细化.智能化.绿色化等趋势发展. 智能环卫依托物联网.AI.大数据等技术, ...

  7. git使用其它

    创建目录 切换到本地新建的dev分支,目录下还是这个目录下的文件.我push一下,指定推送到dev分支,那么dev分支就在远程仓库同步创建,并且文件也是本地这个目录下的文件,一样的. 好像得改个名字才 ...

  8. mongodb的replication与shard分片结合使用详解

    部署脚本 #!/bin/bash #复制集配置 IP='10.0.0.12' #主机ip NA='rs3' #复制集名称 if [ "$1" = "reset" ...

  9. 【论文笔记】GoogLeNet系列

    [深度学习]总目录 Inception技术演进 Inception-V1: 2014年9月,<Going Deeper with Convolutions>提出了Inception模块,在 ...

  10. TensorRT环境配置(VS+opencv4.5)

    1 TensorRT下载 下载与TensorRT相匹配的CUDA和cuDNN版本:https://docs.nvidia.com/deeplearning/tensorrt/archives/tens ...