快乐的一天从AC开始 | 20210709 | P4168

题目链接

早上补昨天的题,被莫名其妙的问题关了,然后就去上班了。

白天自闭看代码看了一天,晚上下班又被这题关了,更加自闭了。

入职一周,啥东西都不会,一行代码没写,学技术还越学不会的东西越多。之前但凡多用点心学技术现在也不至于这样。

带薪自习总觉得内心不安,很怕试用期没过人就没了

明天不上班(

心路历程

题目翻译一下就是区间众数。

众数不满足可减性,主席树被关了。

然后想到莫队,回滚莫队确实可以搞区间众数。但是很不幸,本题强制在线,莫队也被关了。

然后一看数据范围,直接莽分块吧。(暴力美学

思路

首先(a_i le 10^9)太大了,离散化一波,现在(a_i le n)

对于询问([l, r]),如果其属于一个块,那么直接暴力扫一遍就好了。

否则,它就可以至多分成3段,两边的两块不完整的块,以及中间一段完整的块。通过观察可以得到:最终的答案,要么是中间的众数,要么是两边上的数。想象成原本只有中间的一段,然后向两边扩展,只有再两边出现才有可能更新众数。两边上的数只有(O(sqrt{n}))个,这个性质就很nice了。

现在,可以(O(n sqrt{n}))预处理出第(i)块到第(j)块的众数(z_{i, j})。枚举起点,每次令终点加一,再枚举新增这一个块中的数,看能不能更新众数。这样答案的初始值就可以(O(1))得到了。

然后就是枚举两边的数,看([l, r])内这个数出现了多少次,判断能不能更新答案。

  • 可以(O(n sqrt{n}))暴力预处理前(i)块中(j)出现的次数(p_{i, j})。现在可以(o(1))得到中间那一段中某个数出现了多少次。对于每个询问,先遍历一遍两边的数,搞个map存出现的数及其次数。然后遍历map,判断一下就完事了。
  • 口胡:搞(n)vector保存每个数出现的位置,然后每次询问,遍历两边的数,然后两次二分可以确定([l, r])内这个数出现了几次。

完结撒花。

原文地址:https://www.cnblogs.com/zengzk/p/14992861.html