博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CF1207G Indie Album
阅读量:5263 次
发布时间:2019-06-14

本文共 1666 字,大约阅读时间需要 5 分钟。

CF1207G Indie Album

一道很有意思的AC自动机好题。

AC自动机的本质是记录了一棵字典树上所有字符串的所有后缀,所以这道题我们可以充分利用这个性质。

这道题与板子题的不同之处就在于:文本串在不停的变化,每次增加一个字符。

我们先来复习一下AC自动机模版题的流程

  1. 遍历文本串的所有前缀。
  2. 将所有是这个前缀的后缀的模式串出现次数+1。(即沿着fail指针一直走到根,沿途的所有节点都是符合条件的)

而对于这道题,因为文本串每次只会添加一个字符。所以我们在上一个文本串的基础上,加入以当前节点到根组成的字符串的贡献即可。

那这道题的解决方案就比较清晰了:

我们将字符串\(s\)定义为当前字典树节点到根的所有节点组成的字符串,文本串\(s\)对应的模式串出现次数的记为\(t[s]\),将文本串\(s\)对应的答案记为\(ans[s]\)

  1. 建出一个文本串组成的字典树。
  2. 对字典树进行DFS,每走到一个节点,将所有为s后缀的字符串的出现次数\(t\)加1。
  3. 记录答案\(ans[s]=t[s]\)
  4. DFS回溯时,将所有为s后缀的字符串的出现次数\(t\)减1。

因为所有字符串长度和\(T\)的大小关系,\(T^2\)算法是过不了的。但是因为累计答案是在\(fail\)指针构成的树,所以我们可以用数据结构来维护这个东西。复杂度变成了\(T\log T\)

个人感觉这道题的关键在于利用AC自动机“求解单文本串问题时会遍历文本串的所有前缀”这个性质,从而求解特殊的多文本串问题。

#include
#include
#include
#include
#include
#include
#define ll long long#define maxn (int)(4*1e5+1000)using namespace std;int ans[maxn],ch[maxn][30],tr[maxn][30],c[maxn],queue[maxn],n,m,now_insert,tcnt,acnt,fcnt,ver_tr[maxn],fail[maxn],size[maxn],id[maxn];//id指在ac自动机上的点在fail树上的编号bool is_end[maxn];char s[10];struct gg{ int lo,id,mod_ed;string add;//版本和询问的模式串,以及模式串结尾位置在AC自动机上的编号}query[maxn];vector
tr_ver[maxn],fail_son[maxn];vector
so[maxn];//记录每个版本的询问void change(int now,int num) { for(int i=now;i<=fcnt;i+=i&-i){c[i]+=num;}}int sum(int now) { int re=0;for(int i=now;i>=1;i-=i&-i){re+=c[i];}return re;}int insert_ac(string data) { int now=0; for(int i=0;i
>query[i].add;query[i].mod_ed=insert_ac(query[i].add);query[i].id=i; so[query[i].lo].push_back(query[i]); } build_ac(); dfs1(0); dfs2(0,0); for(int i=1;i<=m;i++)printf("%d\n",ans[i]);}

另外,记录一下本题的小故事:

1669439-20190828071536743-1846908207.png

1669439-20190828070837804-1929947596.jpg

转载于:https://www.cnblogs.com/GavinZheng/p/11421730.html

你可能感兴趣的文章
f2fs解析(八)node 管理器中的node_info
查看>>
uilabel的文字连接用button来替代
查看>>
拓扑排序的模板实现
查看>>
HDU 4828 - Grids (Catalan数)
查看>>
NTFS格式 读取MFT信息
查看>>
适配器模式
查看>>
用struct模块解决tcp的粘包问题
查看>>
PsExec.exe执行远程程序
查看>>
抽取、转换和装载介绍(九)小结
查看>>
可以开发着玩一下的web项目
查看>>
oracle 中 UPDATE nowait 的使用方法
查看>>
二叉查找树中节点的删除
查看>>
JOGL简介与安装
查看>>
linux Ubuntu Kali 安装flash
查看>>
蜕变成蝶~Linux设备驱动之异步通知和异步I/O
查看>>
JavaScript超链接设置打开窗口
查看>>
Django:学习笔记(7)——模型进阶
查看>>
hdoj2042
查看>>
用js实现帧动画
查看>>
Quartz使用总结
查看>>