发现写过文,摘抄下来。
前置芝士:CDQ分治
读题之后容易发现最后一个输入没用
可以发现每次输出的答案后一个都比前一个小
看似是废话,那我们思考一下小了多少呢?
很明显是删除元素对答案的负贡献。每个答案都多计算一个元素的负贡献,可以考虑用类似前缀和的方法。先计算原序列总贡献,再递推每个删除元素的负贡献。
问题转化为:如何寻找每次删除操作的负贡献?
先对代码进行简化,不需要去重,并考虑用sort直接实现。接下来可以将元素被删时间TimeTimeTime看作第三维的属性,注意到对于删除操作 iii,其负贡献的倒数为序列中满足 Timei<Timej,Time_i < Time_j,Timei <Timej , Vali<Valj,Val_i<Val_j,Vali <Valj , Posi>PosjPos_i>Pos_jPosi >Posj 或Timei<Timej,Time_i<Time_j,Timei <Timej , Vali>Valj,Val_i>Val_j,Vali >Valj , Posi<PosjPos_i<Pos_jPosi
<Posj 的元素个数。将其转化为三维偏序问题,进行答案运算时不考虑 TimeTimeTime,将序列从左到右遍历统计第一种贡献,再倒序处理第二种贡献。删除时像整体二分,用-1抵消插入操作;在计算贡献时乘上自己的 op ,确保插入操作统计正贡献、删除操作统计负贡献。本题有一定思考难度,请自行理解。
注意到求的是逆序对数量的总和,再看看数据量,不开 long long 见祖宗
Code:Code:Code:
所有解法:
CDQCDQCDQ 分治 O(Nlog2N)O(Nlog^2N)O(Nlog2N)
树状数组套主席树 O(Nlog2N)O(Nlog^2N)O(Nlog2N)
分块 O(NN)O(N\sqrt N)O(NN )
线段树套平衡树 O(NlogN+Mlog2N)O(NlogN+Mlog^2N)O(NlogN+Mlog2N)(甚至题解还有线段树套朴素BST)
K−DK-DK−D 树 O(NN)O(N\sqrt N)O(NN )