分块 + 定期重构.
把树的 dfs 序找出来,问题就变成了区间加,区间询问第 $k$ 小.
如果直接分块 + 询问二分 + 块内二分,复杂度是根号带两只 $\log$ ,跑不过去.
唯一还能利用的性质就是 $len\le 10$ .
如果一个块内最大值和最小值相差很小,就可以记录个数的前缀和,少掉一只 $\log$ .
于是可以给块大小和元素极差分别设一个阈值,当其中一者超过阈值时,就立即新开一个块.
块有分裂的操作,为了方便,可以用一个链表把所有块串起来,方便遍历.
还有一个优化,当我们对边角部分暴力修改时,原来的一块可能会因为极差超过阈值而裂成几个小块.
而这些小块是可能与前后的块进行合并的.
如果每次都检查能否合并,效果并不会很好,我们可以定期将整个数列的分块重构一下.
阈值和重构的周期可能需要
照抄别人的参数手动调一下参.
1 | //%std |