CF1446D Frequency Problem 题解

首先,可以确定,如果整个序列有两个以上众数,那么答案为 \(n\),故考虑只有一个众数 \(x\) 的情况。

接下来还是不好做,还是要枚举每个区间,此时我们可以尝试缩小区间范围,排除无效区间

我们假设最终答案的区间为 \([L,R]\),那么我们尝试把这个区间的众数 \(y,z\) (或更多) 与 \(x\) 联系起来,众数与数在序列中出现次数有关,这个次数记为 \(cnt_{val}\)

首先考虑 \([L,R]\) 区间中,是否有 \(x = y\),如果有,那问题便好做许多,如果没有,我们尝试把区间变为这种情况。

首先,由于我们找的是最长区间,所以我们可以考虑扩大区间来寻找一个更优方案。

容易发现,对于 \([1,n]\) 区间,有 \(cnt_x \ge cnt_y\)。如果 \([L,R]\) 区间众数不包含 \(x\),则 \(cnt_x < cnt_y\),则我们在扩大的过程中,必有区间 \([L',R']\),使得 \(cnt_x = cnt_y\),这样的区间合法且更优

所以我们得出结论:答案子段的众数集合一定包含整个序列的众数 \(x\)

那么我们已经确定 \(x\),只需枚举 \(y\),找出区间使得 \(x,y\) 的出现次数一样多就行了

先考虑简单版本:由于值域较小,我们可以直接枚举 \(y\),考虑怎么找区间,这里出现次数一样多有一个经典做法:把 \(x\) 记为 \(1\)\(y\) 记为 \(-1\),其他记为 \(0\),转化为 \(b\) 序列,则我们记录前缀和 \(s\),再用一个 \(map\) 映射找 \(sum_r = sum_l\) 的地方即可,所以我们把次数关系转化为简单的数值关系

困难版本就不好办,对于这种值域的优化,我们可以想到根号分治,对于出现次数 \(> \sqrt{n}\) 的数,他们种类一定 \(< \sqrt{n}\),可以用简单版本的做法;对于出现次数小于 \(\le \sqrt{n}\) 的数,显然可以枚举出现次数,使用双指针判断是否有至少两个不同的达到这个最大出现次数即可

posted @ 2025-07-19 09:27  huangyuze  阅读(10)  评论(0)    收藏  举报