一个用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 ...
随机推荐
- 20165314 2016-2017-2 《Java程序设计》第7周学习总结
20165314 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 MySQL数据库管理系统 连接MySQL数据库 JDBC 批处理 代码托管
- Android Studio 调用夜神模拟器
操作系统:Windows 10 x64 IDE:Android Studio 3.3 夜神模拟器 首先,启动夜神模拟器.快捷键WIN + R打开运行窗口,输入cmd,启动cmd.exe. 使用cd命令 ...
- (转) Golang的单引号、双引号与反引号
Go语言的字符串类型string在本质上就与其他语言的字符串类型不同: Java的String.C++的std::string以及Python3的str类型都只是定宽字符序列 Go语言的字符串是一个用 ...
- js 打开摄像头方法 (定制摄像头)
var video = document.getElementById("video");if (navigator.mediaDevices && navigat ...
- Ubuntu下创建桌面快捷方式(以Pycharm为例)
之后要在Ubuntu虚拟机上玩PyTorch,安装了Pycharm. 然而每次打开Pycharm需要在其bin目录下进入终端,然后输入sh pycharm.sh,很麻烦.既然Ubuntu是桌面系统,为 ...
- MyBatis - 4.动态SQL
动态 SQL是MyBatis强大特性之一.极大的简化我们拼装SQL的操作. 动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似. MyBatis 采用功能强大的基于 OGNL ...
- LVS(IPVS)了解
从来都只是看文章,现在手工作一下. 参考URL: https://blog.csdn.net/langyue919/article/details/80935197 https://www.cnblo ...
- Top 查看某些或者某个进程(top -p pid)
https://blog.csdn.net/zhangfn2011/article/details/7488746?utm_source=blogxgwz5
- java进阶书籍推荐(不包括基础)
个人认为看书有两点好处: 能出版出来的书一定是经过反复的思考.雕琢和审核的,因此从专业性的角度来说,一本好书的价值远超其他资料 对着书上的代码自己敲的时候方便 “看完书之后再次提升自我的最好途径是看一 ...
- Linux-GLIBCXX版本过低导致编译错误--version `GLIBCXX_3.4.20' not found
最近在CentOS6.2上安装protobuf2.4.1,编译的时候出现如下错误: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not fo ...