问题陈述是这样的:给出一个N< 500 000个不同的数字,找到所需的相邻元素的最小交换数,使得没有数字具有两个更大的邻居。号码只能与邻居交换 给出提示:使用段树或fenwick树。
我真的不知道如何使用求和树来解决这个问题。
示例输入:
Input 1:
5 (amount of elements in the list)
3 1 4 2 0
output 1: 1
input 2:
6
4 5 2 0 1 3
output 2: 4
答案 0 :(得分:1)
我可以在O(n log n)时间和O(n)额外空间中完成。但首先让我们看一下我之前提到的二次解决方案:
,而输入列表包含两个以上的元素
为什么这样做?首先,让我们看一下需要零交换的序列如何。由于没有重复,如果最低元素在任何一端但在任何一端,它被两个元素包围,这两个元素都更大,违反了要求,因此最低元素必须位于其中一个末端。递归到排除这个元素的子序列。要使序列进入这种状态:至少需要涉及最低元素的交换,如贪婪算法需要将最低元素移动到一端,并且由于涉及最低元素的交换不会改变其余元素的相对顺序,将它们重新排序到前线也没有任何惩罚。
不幸的是,用列表实现这个是二次方的。你怎么让它更快?有一个手指树跟踪每个子树的子树权重和最小值,并在删除单个最小值时更新这些:
初始化树:首先,将列表中的每个元素视为一个元素子列表,其最小值等于其值。然后,当您有多个子列表时,将子序列成对分组,构建子序列树。序列的长度是两半长度的总和,其最小值等于两半的最小值。
在跟踪序列中的索引时从子序列中删除最小值: