[ARC159F] Good Division 题解

[ARC159F] Good Division 题解

首先对于题目要求的划分方式转化一下,转化为划分的每一段都没有 绝对众数,可以证明这与题目中的要求是完全等价的,证明如下:

充分性:考虑构造一种操作方法,就是每次操作都消去一个出现次数最多的数,按照这样操作可以保证每次操作之后该区间仍然不会出现绝对众数,故按此方法可以清空整个区间。

必要性:考虑该区间有绝对众数,容易发现无论如何操作最终仍旧会剩下若干相同的数,剩下的数为最开始的绝对众数(证明方法类似于摩尔投票)。

有了这一步转化之后考虑如何去做。首先可以暴力 DP,设 dpi 表示对前 i 个数进行划分,并且以 i 为右端点划分最后一段的方案数,那么有转移:

dpi=[j+1,i]无绝对众数dpj

复杂度 O(n2)。考虑如何优化:

有一个比较经典的结论:

对于一个序列 {an},该序列的所有前缀中出现过的绝对众数的种类数为 O(logn)

证明可以感性理解一下:当我们从序列一段往另一端遍历的过程中依次加入元素,如果能够出现一个 新的 绝对众数 x 说明 x 的出现次数已经超过了之前的绝对众数 y 的出现次数,那么说明出现 新的 绝对众数 x 时序列长度至少乘 2,所以说绝对众数种类数为 O(logn)

那么比较显然我们可以尝试从绝对众数种类数方面去优化 DP。我最初的想法是将 DP 转移写成如下形式:

dpi=j=0i1dpjx=12n[j+1,i]的绝对众数为xdpj

这样第一维转移只用枚举 O(logn) 次。但是第二维仍旧不好判断 x 是否是其区间众数。

但第二维转移跟序列上的区间有关,所以可以尝试 cdq 分治!

每一次我们计算 dpl1mid1 对于 dpmid+1r 的贡献,也就是说在这一层我们统计所有 i 所在段跨过 mid 的转移。而所有跨过 mid 的区间的绝对众数种类数仍旧是 O(logn) 种,证明类似,所以说分治之后就可以枚举绝对众数 x 然后将所有 ai=x 的地方设为 1,其余地方设成 1,然后暴力做一遍前缀和,统计即可,具体的,若设 sumii 的前缀和,则有转移:

dpi=j[l1,mid1]dpjj[l1,mid1]sumi>sumjdpj

可以树状数组维护,复杂度 O(nlog3n)。但其实树状数组可以省掉,因为发现 sumi 的范围是 O(rl+1),所以说可以先预处理出来 prei 表示:

prei=j[l1,mid1]sumjidpj

这一步是 O(rl+1) 的,所以最终复杂度为 O(nlog2n)代码如下

posted @   _zyc  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示