既然去重,则可以考虑每一种数的贡献。
实际上就是这一种数在 [l,r] 的子序列中出现的次数。
对于某种数,设其在区间内出现次数为 k,则不包含这种树的子序列有 2r−l+1−k 个。
而这个区间总共的子序列有 2r−l+1 个。
这样显然不能过。
考虑把贡献次数相同,即出现的子序列个数相同,也即出现次数相同的数放在一起做。
然后莫队。
那么又注意到实际上不同的出现次数只会有 O(√n) 种。
因为要最大化不同的出现次数的种数,则显然要从小的出现次数开始选。
这个区间的长度本身是 O(n) 的,那么根据等差数列求和公式可得最多有 O(√n) 种。
然后就 OJBK 辣。
注意每个询问的模数是不同的,那是不是得带个 log 算快速幂呢?
并不,可以预处理模意义下的 1,2,22,23,…,2T 和 1,2T,22T,...,2⌊nT⌋T,其中 T 为块大小。
如果用 set/unordered_set 来存储不同的出现次数的话常数会很大,需要高超的卡常技巧彩星。
然鹅实际上可以直接用一个 vector 来存,转移询问的时候保留上一次的值,并且不删除无用值,而是转移完之后重构 vector,此时再将无用值删去。
复杂度可以根据莫队的移动次数和上述不同出现次数的结论得到。
代码:
1 |
|