摩尔投票法

定义绝对众数为出现次数超过一半的数。

注意到如下事实:每轮消去一个绝对众数和一个其余元素,最后剩下的一定是绝对众数。

考虑模拟上述过程。维护二元组 \((\text{val},\text{cnt})\),其中:

  • \(\text{val}\) 表示当前候选元素。
  • \(\text{cnt}\) 表示抵消后 \(\text{cnt}\) 获得的票数。

新元素 \(x\) 可以被视作二元组 \((x,1)\)。对 \((\text{val}_1,\text{cnt}_1)\)\((\text{val}_2,\text{cnt}_2)\),对信息的合并进行讨论:

  • \(\text{val}_1=\text{val}_2\),票数相加为 \((\text{val},\text{cnt}_1+\text{cnt}_2)\)
  • \(\text{val}_1 \ne \text{val}_2\),取票数较大者,并做抵消操作。
    • \(\text{cnt}_1 \ge \text{cnt}_2\),合并为 \((\text{val}_1,\text{cnt}_1-\text{cnt}_2)\)
    • \(\text{cnt}_1 < \text{cnt}_2\),合并为 \((\text{val}_2,\text{cnt}_2-\text{cnt}_1)\)

上述过程称为摩尔投票法。若序列存在绝对众数,则对其做摩尔投票后,所得的 \(\text{val}\) 即为绝对众数。否则 \(\text{val}\) 是无效值。

考察 \((\text{val},\text{cnt})\) 合并满足结合律、交换律,且有单位元 \((\text{null}, 0)\)。故称摩尔投票信息构成交换幺半群。这允许我们使用数据结构来维护绝对众数。

P3765 总统选举

维护一个长为 \(n\) 的序列 \(a_i\),支持 \(q\) 次操作:

  • 给定 \(i,x\),令 \(a_ i \gets x\)
  • 给定 \(l,r\),查询 \([l,r]\) 的绝对众数,或报告不存在。

\(n,q \le 5 \times 10^5\)\(1\le a_i \le n\),5 秒,125 MB。

:::::success[题解]

若绝对众数存在,则可以用线段树维护摩尔投票解决。

对于摩尔投票得到的答案 \(\text{val}\),我们需要在 \([l,r]\) 中查询其出现次数。可以对每个值开一棵平衡树,查询 \(l\)\(r+1\) 的排名后相减得到。

复杂度 \(O(q \log n)\)

:::::

P8496 [NOI2022] 众数

posted @ 2026-08-01 17:30  stripe_python  阅读(0)  评论(0)    收藏  举报