hihoCoder #1783 又一个重复计数
题目大意
给定一个长度为 $n$ 的字符串 $S$,定义函数 $f(S)$ 表示 $S$ 的不同回文子串的个数。对于 $1\le l \le r \le n$,定义 $S[l,r]$ 为字符串 $S$ 的第 $l$ 个字符到第 $r$ 个字符组成的字符串。
求 $\sum_{l= 1}^{n} \sum_{r=l}^{n} (r - l + 1) f(S[l, r]) $ 。
分析
前置知识
长度为 $n$ 的字符串至多有 $n$ 个不同的回文子串。
提示:可以从 Manacher 算法的过程与性质着手去证明。长为 $n$ 的序列共有 $\binom{n+1}{2}$ 个区间,所有区间的长度之和是 $\binom{n+2}{3}$ 。
证明:只证后一部分,前一部分的证明是类似的。考虑从 $n+2$ 个物品中选出三个物品的某个具体结果。设所选出的三个物品的编号从小到大依次为 $a, b, c$ 。若 $c \le n$,把此结果与区间 $[a,c]$ 相对应;若 $ c > n$ 且 $b \le n$,把此结果与区间 $[a, b]$ 对应;若 $b > n$ 且 $c > n$,把此结果与区间 $[a,a]$ 相对应。不难验证:(1)每个组合结果都与唯一的区间相对应;(2)每个长度为 $l$ 的区间都有且仅有 $l$ 个组合结果与之对应。证毕。
解法核心
一个回文子串 $P$ 对答案的贡献为「包含 $P$ 的区间」的长度之和。我们考虑「不包含 $P$ 的区间」的长度之和 $N_P$,则 $P$ 对答案的贡献为 $\binom{n+2}{3} - N_P$ 。
下面考虑如何计算 $N_P$ 。
将「不包含 $P$ 的区间」按照其右端点 $r$ 分类。设 $P$ 在 $S$ 中的「出现位置」从左到右依次是 $[l_1, r_1], [l_2, r_2], \dots, [l_k, r_k]$,它们都满足 $r_i - l_i + 1 = |P|$,$|P|$ 表示 $P$ 的长度。
对于 $1\le r \le r_1$ 的情况,我们有 $1 \le l \le r$,这些区间的长度之和(即它们对 $N_P$ 的贡献)亦即「$[1, r_1 -1]$ 的子区间长度之和」为 $\binom{r_1 + 1}{3}$ 。
对于 $r_i \le r < r_{i+1}$ 的情况(不妨定义 $r_{k+1} = n+1$),我们有 $l_i < l \le r$,这些区间的长度之和为 $\binom{r_i+1 - r_i + |P|}{3} - \binom{|P|}{3}$ 。
推导:「区间 $[l_{i}+1, r_{i+1} -1]$ 的子区间长度之和」 - 「区间 $[l_i + 1, r_i-1]$ 的子区间长度之和」;亦即 $\binom{r_{i+1} - l_{i} + 1}{3} - \binom{r_i - l_i + 1}{3}$,将 $l_i = r_i - |P| + 1$ 代入即得 $\binom{r_{i+1} -r_i + |P|}{3} - \binom{|P|}{3} $,是关于 $P$ 和 $r_{i+1} - r_{i}$ 的三次多项式。为了书写简便,令 $x = r_{i+1} - r_{i} $,
\begin{aligned}
\binom{x+ |P|}{3} - \binom{|P|}{3} &= \frac16 [(x+|P|) (x + |P| -1) (x+ |P| - 2) - |P| (|P| - 1) (|P| - 2) ] \\
&= \frac16 [x^3 + (3|P| - 3 ) x ^ 2 + (3|P|^2 - 6|P| + 2) x]
\end{aligned}我们可以使用 Manacher 算法配合 Hash 或者直接用 eertree 找出所有回文子串,使用后缀数组或者后缀自动机配合倍增算法识别出每个回文子串出现位置的右端点,通过启发式合并或者可持久化线段树合并或者其他数据结构维护 $(r_{i+1} - r_i)^e$ 的和,其中 $e = 1, 2, 3$ 。时间复杂度为 $n\log n$ 。
上面引自出题人发布的题解,我补了一些细节。
这道题我是照着题解的思路做出来的。我的做法是用 Manacher 算法找出所有回文子串,用字符串哈希给每个不同的回文子串赋一个编号,编号从 $0$ 开始。题解中最后一段红字那句话我没读懂(后缀数组我学过,但不熟悉;后缀自动机我不会;我也不懂其中提到的「倍增算法」是什么),于是我转而去维护一个回文子串 $P$ 出现位置的中心 $c_1, c_2, \dots, c_k$ 。
子串 $S[l, r]$ 的中心定义为 $\lceil (l+r)/2 \rceil$,亦即,长度为奇数的串中心为中间那个位置,长度为偶数的串的中心为后半部分开头那个位置。注意到,$r_{i+1} - r_{i}$ 即 $c_{i+1} - c_{i}$ 。
注意到回文子串的中心构成一种树形结构:较长的回文子串的中心也是它所包含的较短的回文子串的中心,例如 aba 的中心亦是 b 的中心,abba 的中心亦是 bb 的中心。我们建一棵树:每个节点代表一个回文串,回文子串 $P$ 的父亲是去掉 $P$ 两端的字符所得的回文串。每个节点都对应着一个集合 $C_P$——这个节点所代表的回文串 $P$ 在 $S$ 出现位置的中心的集合。
我们自底(叶子)向上(根)启发式合并各个节点对应的集合,得到 $C_P$ 之后就可以算出 $N_P$ 。
实现细节
用 Manacher + 哈希时,一般都是把回文串的一半(通常是右半边)进行哈希编码,因此这道题宜将长度为奇数和长度为偶数的回文串分开计算,否则
ab既有可能是aba的半边,也有可能是abba的半边,难以区分。按照「节点 $v$ 的编号一定比其父节点 $p$ 的编号大」的原则给节点(即回文子串)编号。记录下每个节点的父亲的编号,按编号从大到小合并就相当于在树上自底向上合并。
要注意哈希冲突的问题,如果你用的哈希被卡了,不妨换一个底数或模数试试。我以 257 为底数,$10^9+7$ 为模数,被卡了;把底数换成 131 就过了。
总结
现在来考虑 Manacher 算法和字符串哈希在这个方法里起到的作用。
- 找到所有的回文子串,并给不同的回文子串编号。
- 支持 $O(1)$ 查询回文子串 $P$ 的父亲的编号。
如果有一种自动机能支持上述两种操作,那么就可以替代 Manacher + 哈希。
hihoCoder #1783 又一个重复计数的更多相关文章
- ASP.NET MVC的Ajax.ActionLink 的HttpMethod="Get" 一个重复请求的BUG
这段时间使用BootStrap+Asp.net Mvc5开发项目,Ajax.ActionLink遇到一个重复提交的BUG,代码如下: @model IList<WFModel.WF_Temp&g ...
- 【剑指offer】找出数组中任意一个重复的数字,C++实现
原创博文,转载请注明出处! # 题目 # 思路 对于长度为n的数组,范围为0~n-1的数字而言,如果不粗在重复数字,则排序后数组元素和数组角标相同.如果存在重复数字,则在排序的过程中会出现不同下标对应 ...
- SSAS 非重复计数
在SSAS设计时,对商品编号列非重复计数:
- hihoCoder 后缀自动机三·重复旋律6
后缀自动机三·重复旋律6 时间限制:15000ms 单点时限:3000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数列. 现在小Hi ...
- hihocoder 后缀自动机四·重复旋律6
题目 对于\(k\in[1,n]\)求出长度为\(k\)的子串出现次数最多的出现了多少次 我直到现在才理解后缀自动机上的子树和是什么意思 非常显然的一点是 \[endpos(link(u))⊇endp ...
- hihocoder 后缀自动机五·重复旋律8 求循环同构串出现的次数
描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成的数列. 小Hi发现旋律可以循环,每次把一段旋律里面最前面一个音换到最后面就成为了原旋律的“循环相似旋律”,还可以 ...
- 在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3
// test14.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...
- hihocoder 后缀自动机四·重复旋律7
题目 在\(DAG\)上跑一个\(dp\)就好了 设\(ans_i\)表示到了\(SAM\)的\(i\)位置上所有的子串形成的数的和,之后我们顺便记录一个方案数\(d_i\) 之后我们直接转移就好了 ...
- SSAS GUID 添加 行计数,非重复计数 等 遇到的莫名其妙的问题
在基于某个GUID 进行非重复性计数时 需要对GUID 转换类型,如:CAST(ColumnName as varchar(36)) 可参考:http://stackoverflow.com/ques ...
随机推荐
- 四面体ply格式文件图和数据对应关系分析
通过一个简单的文件来理解ply格式的文件是有所帮助的,我在网上找了一个四面体的ply文件,我通过meshlab打开看到的效果如下所示,我录制成gif文件,希望可以从不同角度展示出来: 同时我截图少许, ...
- 简述apache,php,mysql三者的关系
转自:http://blog.csdn.net/w1365966490/article/details/8218959 Apache web 服务器软件.同类产品有微软的 IIS 等.功能是让某台电脑 ...
- C# 创建和初始化集合对象
一. 引言 C# 3.0中新的对象初始化器是一种简单的语法特征-借助于这种特征,对象的构建和初始化变得非常简单.假定你有一个类Student,它看起来有如下样子: public class Stude ...
- react 的虚拟dom
前端优化的主要方面就是减少页面的DOM操作,减少重排和重绘,React在这方面做了优化,采用了所谓的虚拟DOM,其实我们平时也会遇到虚拟DOM,只是你没有注意罢了,请听我娓娓道来. 所谓的虚拟DOM ...
- vue学习之路 - 2.基本操作(上)
基本操作(上) 本章节简介: vue的安装 vue实例创建 数据绑定渲染 表单数据双向绑定 事件处理 安装 安装方式有三种: 一.vue官网直接下载 http://vuejs.org/js/vue.m ...
- 微信小程序页面跳转绑定点击事件
https://www.cnblogs.com/mrszhou/p/7931747.html
- Arguments Optional-freecodecamp算法题目
Arguments Optional 1.要求 创建一个计算两个参数之和的 function.如果只有一个参数,则返回一个 function,该 function 请求一个参数然后返回求和的结果. 如 ...
- 【转载】SQLServer中char、varchar、nchar、nvarchar的区别:
(1) 定义: char: 固定长度,存储ANSI字符,不足的补英文半角空格. nchar: 固定长度,存储Unicode字符,不足的补英文半角空格 varchar: 可变长度 ...
- mysql 绿色版 安装
1.下载mysql的绿色版压缩包.(自行百度) 2.自行规划目录解压 3.安装 注意:我遇到的两种版本的安装方法(暂时按照解压后的目录中是否含有data目录来区分) 3.1 无data目录(我用到的的 ...
- 二十三、MySQL 事务
MySQL 事务 MySQL 事务主要用于处理操作量大,复杂度高的数据.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数 ...