先对序列按照 $B$ 进行分块。每块内部维护一个归并排序的线段树来刻画信息,每次做 $O(len)$ 的 pushup,块内更新的复杂度是 $O(B)$ 的。
一次查询就有 $O(\frac{m}{B})$ 个区间,外加 $O(B)$ 个散块的单点查询。注意到由于总和正确,所以树剖并不会带来额外的复杂度,只需要研究一个序列的问题。每次在当前每个块归并好的序列上进行二分,复杂度是 $O(\frac{m}{B}\log B+B)$ 的,总复杂度 $O(n\sqrt{n\log n})$。
考虑对于块之间合并也建立线段树,递归到一个整块代表的区间时需要得知排名。
对于全局的线段树,维护 $S_o$ 表示 $o$ 节点子树中按照 $d$ 排序后形成的序列,而附带权值的信息 $T$ 只对完整块内的存在。问题在于我们并不能对每个 $S$ 都进行二分。每个 $S_o$ 都是由 $S_{lson},S_{rson}$ 归并排序得到的。可以从上往下,假设已知 $x$ 在 $S_o$ 的排名,现在要求出 $x$ 在 $S_{lson},S_{rson}$ 的排名,处理 $S_o$ 每个前缀中有多少个来自于 $S_{lson}$,这样最终只需要在根节点的序列上进行二分,下面的排名查询都是 $O(1)$。一次查询就能不带 $\log$。
总时间复杂度 $O(n\sqrt n+n\log^2n)$。