P3521 ROT-Tree Rotations
考点
- 线段树合并
- 逆序对
题解
1 |
|
思路
通过观察可以发现,子树之间的交换并不会影响到父树,如图所示:

交换A
的子树,会影响后续345
的逆序对吗?并不会。
交换C
的子树,会影响前面123
的逆序对吗?也不会。
交换B
的子树,会影响后续45
的逆序对吗?还是不会,但是会影响A
和3
的逆序对。
所以总的思路出来了:
自底向上,枚举所有节点,其交换、或不交换子树得到的逆序对个数,取二者较小值为结果,所有节点的结果求和就得到了答案。
由于需要知道每个点的俩子树值域组成,且题目也说值域只有2e5
,那么对每个点开权值线段树,向父结点依次合并即可。
现在的关键是,我知道左、右子树的权值线段树,怎样计算左子树对右子树的逆序对贡献呢?
假设当前有序列12345 12345
,当前结点区间为[1, 10]
,那么左子树区间为[1, 5]
,右子树区间为[6, 10]
,
在两子树的线段树合并过程中可以发现,逆序对可以即时得出。

每一层的红色区域个数 * 绿色区域个数
就等于该层的逆序对贡献,也就是左子树的右孩子 * 右子树的左孩子
;
我们自上而下看看。
左子树的4
、5
肯定对右子树的[1, 3]
有贡献;
左子树的3
也对右子树的[1, 2]
有贡献,左子树的5
也对右子树的4
有贡献;
左子树的2
也对右子树的1
有贡献。
自此,左子树对右子树的所有贡献不重不漏地整理完了,非常巧妙!