zoukankan      html  css  js  c++  java
  • 【BZOJ】2434: [Noi2011]阿狸的打字机 AC自动机+树状数组+DFS序

    【题意】阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机。打字机上只有28个按键,分别印有26个小写英文字母和'B'、'P'两个字母。

    经阿狸研究发现,这个打字机是这样工作的:

    l 输入小写字母,打字机的一个凹槽中会加入这个字母(这个字母加在凹槽的最后)。

    l 按一下印有'B'的按键,打字机凹槽中最后一个字母会消失。

    l 按一下印有'P'的按键,打字机会在纸上打印出凹槽中现有的所有字母并换行,但凹槽中的字母不会消失。

    我们把纸上打印出来的字符串从1开始顺序编号,一直到n。打字机有一个非常有趣的功能,在打字机中暗藏一个带数字的小键盘,在小键盘上输入两个数(x,y)(其中1≤x,y≤n),打字机会显示第x个打印的字符串在第y个打印的字符串中出现了多少次。

    【算法】AC自动机+树状数组+DFS序

    【题解】首先根据操作序列建AC自动机,"B"就返回跳过来的节点,“P”就标记为一个串的结尾节点。

    询问AC自动机中一个串B在另一个串A中出现几次?

    从根开始走整个串A,标记到达的节点为1,那么就是询问B在fail树上的子树中有多少节点为1。

    询问可以用树状数组维护DFS序来区间查询,这部分复杂度O(n log n)。那怎么修改询问串A?

    将询问离线按串A的编号顺序排列(本质上是按DFS序排序),利用一个性质【对每个点入栈+1,出栈-1,那每个点到根的前缀和就是到根的路径(星系探索)】。

    所以按顺序枚举串A,加入新节点+1,“B”退格-1,这些+1-1都在树状数组上单点修改,遇到询问就回答(相当于前缀和)。因为串A都是AC自动机中的串,所以不会有fail的问题。

    总复杂度O(n log n)。

  • 相关阅读:
    HDU
    HDU-1166 敌兵布阵 (基础线段树)
    Matrices with XOR property (暴力)
    CF-825E Minimal Labels (反向拓扑)
    CodeForces-1144E Median String (模拟)
    操作文件和目录
    文件读写
    装饰器
    数据结构和算法
    Scrapy shell调试返回403错误
  • 原文地址:https://www.cnblogs.com/onioncyc/p/8943954.html
Copyright © 2011-2022 走看看