思路:先离散化到 b 里面,然后 firi 表示 b 数组中值为 i 的数字原来的值是多少。
roomi 表示值为 i 的元素在 b 中出现的次数。
get_time 求的是 [l,r] 中 x 出现的次数。
numi 表示第 i 个块中出现次数最多的元素的次数,IDi 表示第 i 块中出现次数最多的元素中最小的元素的值。
bf 用来求出,[l,r] 中的每个元素在 [L,R] 中出现的次数的最大值,并返回最大值出现的次数和数值。(若有多个次数相等,则取数值小的)
pii A = bf(l, R[p], l, r), B = bf(L[q], r, l, r);
是对左右两端散的块进行处理。
for (int i = p + 1; i <= q - 1; i++) {
int x = get_times(ID[i], l, r);
if (x > val || (x == val && (id == INF || id > ID[i]))) val = x, id = ID[i];
}
是在整块中找到次数最多的值(若次数同样多取最小值)。
最后返回左右两边以及整块中出现的次数的最大值的元素的值。
但是,我在 make_pair 的时候都选择了把第二个值(即最多次数的元素值)乘上 −1,这是因为题目要求若次数相同返回值最小的。最后返回答案的时候再乘上 −1。
拍了 2000 组的数据,但是一组比较小的数据都没拍出来,只有 10pts/kk。
代码:Link。