拓展摩尔投票

拓展摩尔投票

前言

了解到这个东西是从 CF840D 来的,我觉得这个题很典很套路,并且做法很多也很妙,并且我断定这种出现次数占比超过一个值的题一定有一种通法,于是在题解区了解到了拓展摩尔投票。

算法

考虑是摩尔投票的拓展,也就是我们可以在 \(O(nk)\) 的时间内得到 \(k - 1\) 个数,并且所有频率严格大于 \(\frac{1}{k}\) 的数都在这 \(k - 1\) 个数里面,但可能不足 \(k - 1\) 个数,所以这些数里面有些不满足条件,但是所有的满足条件的一定都在里面。

算法:一直删去不同的 \(k\) 个数即可。

简单证明:
考虑如果这个数所占的频率大于 \(\frac{1}{k}\),如果他被删一个,频率不变,因为总量变了,如果没删,那占比就更大了,所以他们一定活到最后。

性质

做一些定义来方便讲解,我定义 calc(A) 为对 \(A\) 序列做一次摩尔投票,返回值为 \(k - 1\) 个元素,元素信息有值和出现次数两个。\(A + B\)\(A\) 序列和 \(B\) 序列两个首尾相接。

结合律:calc(A + B) = calc(calc(A) + calc(B))。

也就是我们可以 \(O(k^2)\) 的合并两个区间,并且还可以 \(O(k)\) 的插入一个元素。这就给我们维护区间信息提供了可能性。

例题

考虑只要和出现次数大于某个数相关的问题我们都可以直接用拓展摩尔投票加线段树维护,并且我们还可以支持 区间赋值和区间加减的修改操作。
题目: CF643G CF840D

posted @ 2024-09-18 21:50  qqrj  阅读(46)  评论(0)    收藏  举报