具体的题解就看OI-wiki上面的就好了,但是对上面的题解做一些解释
题解首先说按照 a a a排序,其实是按照 a a a为第一关键字, b b b为第二关键字, c c c为第三关键字排序再离散化
为什么要这么做?我们来看一下CDQ分治的具体过程
当 s o l v e ( l , m i d ) solve(l,mid) solve(l,mid)和 s o l v e ( m i d + 1 , r ) solve(mid+1,r) solve(mid+1,r)解决完后,我们只需要解决点对 ( i , j ) (i,j) (i,j)的问题(我们枚举的是 j j j,计算的是 f ( j ) f(j) f(j)),其中 i i i属于 [ l , m i d ] [l,mid] [l,mid]且 j j j属于 [ m i d + 1 , r ] [mid+1,r] [mid+1,r]或者 i i i属于 [ m i d + 1 , r ] [mid+1,r] [mid+1,r]且 j j j属于 [ l , m i d ] [l,mid] [l,mid]
我们先来看前一种情况,这种情况就看OI-wiki就好了,上面除了 ≤ ≤ ≤打成了 < < <没啥错
然后来看第二种情况,由于我们最开始的排序和离散化,此时不可能存在一个数对 ( i , j ) (i,j) (i,j)使得 a j ≥ a i , b j ≥ b i , c j ≥ c i a_j≥a_i,b_j≥b_i,c_j≥c_i aj≥ai,bj≥bi,cj≥ci,所以根本不用考虑第二种情况(所以题解说的离散化是保证时间复杂度的,其实不尽然,其实是保证正确性的);如果最开始只是按照 a i a_i ai为关键字排序,可能在某次 s o l v e solve solve的区间 [ l , r ] [l,r] [l,r]中,原序列(指最开始按照 a i a_i ai排序之后的 [ l , r ] [l,r] [l,r]而不是在 s o l v e solve solve递归之后已经经过 b i b_i bi排序后的数组) [ x , m i d ] [x,mid] [x,mid]和 [ m i d + 1 , y ] [mid+1,y] [mid+1,y]的元素的 a a a是相等的,因此第二种情况是可能存在的,但是却没有办法统计了(所以说离散化是保证正确性的,当然这里保证正确性就是保证时间复杂度)
然后注意最后统计答案的时候,由于我们离散化了,是没有办法统计三个属性值相等的元素之间的互相影响的,因为最后的下标不是 u e . r e s ue.res ue.res,而是 u e . r e s + u e . c n t − 1 ue.res+ue.cnt-1 ue.res+ue.cnt−1
update 2024.7.18
其实单纯按照 a a a排序也可以,最后要单独统计一下上面说的特殊情况而已,可知时间复杂度并不会变化