一个用SAM维护多个串的根号特技
一个用SAM维护多个串的根号特技
基本介绍
在多个串的字符串题中,往往会出现一类题需要用到某个子串是否在一些母串中出现。此时对于 \(\text{parent}\) 树的 \(\text{right}\) 集合而言,问题并不关心某个具体位置而只关心是否有某个 \(\text{endpos}\) 在指定母串中。
那么对于 \(\text{parent}\) 树上的来自同一个母串的节点而言,其对祖先的贡献都是可以替代的,并不需要重复标记其某个祖先 \(\text{right}\) 集合中是否存在一个 \(\text{endpos}\) 来自这个母串。
于是我们维护来自这个母串的所有节点对 \(\text{parent}\) 树的贡献复杂度等价于所有来自这个母串的叶子节点在 \(\text{parent}\) 树上的并的大小。(此处叶子指的是来自这个母串且其子树内不存在来自这个母串节点的节点)
分析这些叶子在树上的并的大小的具体规模,有一个显然的上界就是 \(\sum_{i=1}^{n}2len_i-1\) ,其中 \(len_i\) 是第 \(i\) 个串的长度,对其建后缀自动机的节点数上界为 \(2len_i-1\) ,对 \(n\) 个串一起建可以得到这个显然的上界。
观察这棵并起来的树的性质可以发现,这棵树上的每一个节点的 \(\text{right}\) 集合都包含来自这个母串的 \(\text{endpos}\) ,而每个节点的父节点都是该节点所代表串的一个后缀且至少长度减少 \(1\) 。那么考虑这个串每一个前缀的最大贡献就是这个前缀的长度,所以可以得到另外一个上界 \(len_i^2\) 。
假设这 \(n\) 个串的总长为 \(S\) ,那么 \(\sum_{i=1}^{n}2len_i-1\) 可以看做 \(2S\) ,所以对于每一个母串都维护贡献的复杂度是 \(\sum_{i=1}^n \min(2S, len_i^2)\) ,且 \(\sum_{i=1}^n len_i = S\) 。根据均值不等式可以得到 \(n\) 和 \(len_i\) 都取 \(\sqrt{2S}\) 时达到上界,总复杂度 \(O(S\sqrt{2S})\) 。
然而事实上后面那个下界不容易卡满,因为你需要构造一个字符串其每一个前缀都能在 \(\text{parent}\) 树上分支出最长的一条链,所以这个根号实际上跑起来比某些大常数的一个 \(log\) 做法还快。
例题
BZOJ3277 字符串
题意:给出 \(n\) 个字符串,对于每一个字符串求出其有多少个子串在至少 \(k\) 个字符串中出现过。
可以说是这个特技的模板题了,不过线段树合并可以做 \(O(nlogn)\) ,这里就只说根号做法吧。建出后缀自动机后枚举每一个串的叶子节点暴力往上跳给祖先节点出现在不同的母串的次数 \(+1\) 即可,已经被别的该串节点遍历过就跳出,复杂度就是上述的 \(O(S\sqrt{2S})\) 。
NOI2018 你的名字
题意:对于每一个询问串,求出其有多少个不同子串在母串的 \([L, R]\) 之间出现过。
将问题转化为求有多少个子串在询问串和母串的 \([L, R]\) 之间共同出现即可,暴力枚举的同时额外加一个线段树合并判是否在 \([L, R]\) 即可,复杂度 \(O(S\sqrt{2S}logS)\) 。不过套上 \(log\) 以后会因为第二个上界被卡高后被叉掉,但是 \(68pts\) 不需要线段树合并判断,可以确保通过。实际上3s内跑过了所有测试点
Sum of Squares of the Occurrence Counts 加强版
没加强之前这个特技不能做
题意:给出 \(n\) 个串,对于每一个串 \(i\) 求出其所有子串在串 \([1,i]\) 之间的出现次数的平方和。
对于所有串建后缀自动机,用线段树合并维护出 \(\text{parent}\) 树上每一个节点拥有来自哪几种母串的 \(\text{endpos}\) ,以及每一种母串对应的 \(\text{endpos}\) 数量。考虑每一个母串对所有线段树大小之和的贡献就是叶子的并,于是暴力遍历合并后的每一棵线段树的总复杂度就是 \(O(S\sqrt{2S})\) 。直接在线段树上暴力统计每一个 \(\text{parent}\) 树上节点对每一个串的答案的贡献即可,总复杂度 \(O(S\sqrt{2S}+SlogS)\)。
后记
如果你想知道会了这个根号特技有什么用,我也说不清。对于我这种字符串菜鸡来说,写简单好写的做法比套上各种数据结构好调多了,这个特技牺牲了一些时间效率,但是大大简化了思维难度和代码难度。当然如果您是神仙完全可以去秒正解。
一个用SAM维护多个串的根号特技的更多相关文章
- SAM维护的在线LCS
题目大意: 给定两个字符串,存在三种操作,分别是在a,b串末尾加一个字符串,和询问两串的LCS 题解: Get新套路:把两串建在同一SAM上,将重合的位置合并为同一节点,再加个标记数组,如果两者的LC ...
- SAM求多个串的最长公共子串
又学到一个\(SAM\)的新套路QvQ 思路 考虑用其中的一个串建个\(SAM\),然后用其他的串在上面匹配,匹配时更新答案 首先有一个全局变量\(len\),表示当前已匹配的长度.假设目前在点\(u ...
- BZOJ2882 工艺【SAM】 最小循环串
BZOJ2882 工艺 给出一个串,要求其循环同构串中字典序最小的那个 串翻倍建\(SAM\)然后从起点开始贪心的跑\(n\)次即可 当然也能用最小表示法来做 #include<bits/std ...
- Gym - 100570E:Palindrome Query (hash+BIT+二分维护回文串长度)
题意:给定字符串char[],以及Q个操作,操作有三种: 1:pos,chr:把pos位置的字符改为chr 2:pos:问以pos为中心的回文串长度为多长. 3:pos:问以pos,pos+1为中心的 ...
- Solidworks提示字体Arial Unicode MS安装不正确,PDF文件中一个或多个文本字串可能遗失怎么办
从以下网站下载Arial Unicode MS字体,WIN7的直接安装即可,XP的放到windows\fonts文件夹内.重启Solidworks即可 http://font.chinaz.com/1 ...
- luogu P4145 上帝造题的七分钟2 / 花神游历各国 维护区间和&&区间开根号
因为开根号能使数字减小得非常快 所以开不了几次(6次?)很大的数就会变成1..... 所以我们可以维护区间最大值,若最大值>1,则继续递归子树,暴力修改叶节点,否则直接return (好像也可以 ...
- 『转载』判断一个正整数是不是素数,时间复杂度为O(根号n)
原文链接:https://blog.csdn.net/liangdagongjue/article/details/77895170#commentsedit PS:新手上路,实在找不到怎么转载,所以 ...
- CF666E-Forensic Examination【广义SAM,线段树合并】
正题 题目链接:https://www.luogu.com.cn/problem/CF666E 解题思路 给出一个串\(S\)和\(n\)个串\(T_i\).\(m\)次询问\(S_{a\sim b} ...
- ZOJ 3963 Heap Partition set维护。给一个序列,将其划分成尽量少的序列,使每一个序列满足按照顺序构造二叉树,父母的值<=孩子的值。
Heap Partition Time Limit: Seconds Memory Limit: KB Special Judge A sequence S = {s1, s2, ..., sn} i ...
随机推荐
- C++设计模式——观察者模式(转)
前言 之前做了一个性能测试的项目,就是需要对现在的产品进行性能测试,获得测试数据,然后书写测试报告,并提出合理化的改善意见.项目很简单,我们获得了一系列性能测试数据,对于数据,我们需要在Excel中制 ...
- vue-cli watch简单用法
创建一个vue单文件 <template> <div id="test"> <h4 @click="changeMsg()" id ...
- 异常:Keyword not supported: 'data source'的解决办法
将连接字符串中的"换为“'”,一个单引号即可. 详细解释:https://blogs.msdn.microsoft.com/rickandy/2008/12/09/explicit-c ...
- Python语音识别(计算器)
第一步关于导入模块的事,我试了好几个方法才发现在好像win7系统没有语音识别功能,我用了win10的又需要重新下载一个包 这样子,win32com.client模块就可以使用了 import win3 ...
- webpack+vue打包之后输出配置文件修改接口文件
用vue-cli构建的项目通常是采用前后端分离的开发模式,也就是前端与后台完全分离,此时就需要将后台接口地址打包进项目中,but,难道我们只是改个接口地址也要重新打包吗?当然不行了,那就太麻烦了,怎么 ...
- Python自定义-分页器
Python自定义-分页器 分页功能在每个网站都是必要的,对于分页来说,其实就是根据用户的输入计算出应该在数据库表中的起始位置. 1.设定每页显示数据条数 2.用户输入页码(第一页.第二页...) 3 ...
- As/IDEA json自动生成java bean
1.先安装GsonFormat插件:File-->Setting-->Plugins-->GsonFormat-->OK 2.new 一个新的Class空文件,然后 Alt+I ...
- 网页前端 html js 相关
1.注释 1.1HTML 注释 http://www.w3school.com.cn/html/html_comments.asp 注释标签 <!-- 与 --> 用于在 HTML 插入注 ...
- [转]Ubuntu /home下中文目录如何修改成英文?
http://www.linuxidc.com/Linux/2016-05/130873.htm 打开终端,在终端中输入命令: export LANG=en_US xdg-user-dirs-gtk- ...
- OAuth2:客户端证书授权(Client Credentials)类型的开放授权
适应范围 认证服务器不提供像用户数据这样的重要资源,仅仅是有限的只读资源或者一些开放的API.例如使用了第三方的静态文件服务,如Google Storage或Amazon S3.这样,你的应用需要通过 ...