2020.10.4 与 lzc 谈论的关于 Rolling girl 一题跨询问改进

2020.10.4

今天跟 \(\text{lzc}\) 谈论了一道老题 , \(\text{Rolling Girl}\)
这道题其实是有点迷惑的 , 这里再解释一下 (方便自己不会忘记)。

文字难以表述。
一个区间。 若有 \(num_i\) 的出现次数为 \(a\) , \(num_j\) 的出现次数为 \(b\) : \(a-b \leq k\) (\(a>b\)) 的话 , 统计所有满足的 \(a\) 的最大值。
也就是说 , 一个数的出现次数在它与它减去 \(k\) 这段内也是有数的 , 那么它合法 , 并且求这种合法数对的最大值。

一开始我用的是一种垃圾方法 , 题解可以翻一下教堂出题。
大概就是莫队模拟出现次数并且把它们装进分块里面进行维护就可以了。

\(\text{lzc}\) 给我讲了另一种可以让 \(k\) 跨询问的方法 , 这里记录一下。
假若一个数 \(num_i\) 的出现次数 \(a \leq n^{\frac 1 2}\) , 那么它可以在桶里扫。
假若一个数 \(num_i\) 的出现次数 \(a > n^{\frac 1 2}\) , 那么这种数最多有 \(n^{\frac 1 2}\) 个 , 丢进队列里。
每次查询 , 以出现次数为指针 , 在桶里从 \(n^{\frac 1 2}\)\(1\) 跑 , 如果有满足的数对记起来。
那么对于出现次数大于 \(n^{\frac 1 2}\) 的数列 , 对它进行排序。
本来我的想法是直接基数排序可以以 \(6\) 的常数过去 , 但有一个骚方法是 :
先按照它的出现次数有多少个 \(n^{\frac 1 2}\) 分好位置 , 然后再对 \(\text{它的出现次数} \mod n^{\frac 1 2}\) 进行“组内排序” ,也就是 :

\[\{k_3 n^{\frac 1 2}+r_1,k_1 n^{\frac 1 2}+r_2,k_2 n^{\frac 1 2}+r_3,k_1 n^{\frac 1 2}+r_4,k_2 n^{\frac 1 2}+r_3\} \]

\[\downarrow (\text{按照 k 分组}) \]

\[\{k_1 n^{\frac 1 2}+r_2,k_1 n^{\frac 1 2}+r_4,k_2 n^{\frac 1 2}+r_3,k_2 n^{\frac 1 2}+r_3,k_3 n^{\frac 1 2}+r_1\} \]

分完组以后记录每一个组的标志 , 然后全部放在一起桶排 , 取出来的时候分配到各自的组里面。这样复杂度就是 \(O(n^{\frac 1 2})\) 的了。

至此 \(k\) 就可以跨询问了。


已经开学一个多月了 ,
仍然回忆着三个月前垂死的我。
三丫山私立纪念学校。

以后还会继续思考信竞内容 , 当然主要还是看初等数论了。
数据结构还是要多研究 , 脑子才能清醒。
很喜欢和 \(\text{lzc}\) 讨论这些小问题 , 很开心。

posted @ 2020-10-04 19:55  _ARFA  阅读(69)  评论(0编辑  收藏  举报