acwing 逆序对的数量

归并排序的实现与应用
该篇博客详细介绍了归并排序的算法实现,通过一个C++实例展示了如何使用归并排序对整数数组进行排序,并计算了交换次数。内容包括归并排序的递归过程及归并操作。适合对算法感兴趣的读者学习理解。

                                                                  归并排序的应用

#include<iostream>
using namespace std;

const int N=100005;

typedef long long LL;
int q[N],tmp[N];
	int n;


LL merge_sort(int l,int r)
{
	if(l>=r)return 0;
	
	int mid=(l+r)/2;
	
	LL res=merge_sort(l,mid)+merge_sort(mid+1,r);
	
	//归并
	int k=0,i=l,j=mid+1;
	while(i<=mid&&j<=r)
	  if(q[i]<=q[j])tmp[k++]=q[i++];
	  else {
	  tmp[k++]=q[j++];
	  res+=mid-i+1;
          }
    while(i<=mid)tmp[k++]=q[i++];
    while(j<=r)tmp[k++]=q[j++];
	  for(int i=l,j=0;i<=r;i++,j++)q[i]=tmp[j];
	  return res;
	  
}
int main()
{

	cin>>n;
	for(int i=0;i<n;i++)cin>>q[i];
    cout<<merge_sort(0,n-1)<<endl;
    return 0;
	
	
	
	
}

### 计算数组中的逆序对数量 计算数组中的逆序对数量可以通过多种方法实现,其中最常见的是基于 **归并排序** 的改进算法。这种方法的时间复杂度为 \(O(n \log n)\),相较于暴力解法的 \(O(n^2)\) 更加高效。 以下是具体实现: #### 归并排序法 通过修改传统的归并排序,在合并的过程中统计逆序对数量。当右半部分的一个元素被放入临时数组时,说明左半部分剩余的所有元素都比该元素大,因此可以增加相应的逆序对计数[^1]。 ```python def merge_and_count(arr, temp_arr, left, mid, right): i = left # 左子数组起始索引 j = mid + 1 # 右子数组起始索引 k = left # 合并后的数组起始索引 inv_count = 0 while i <= mid and j <= right: if arr[i] <= arr[j]: temp_arr[k] = arr[i] i += 1 else: temp_arr[k] = arr[j] inv_count += (mid - i + 1) # 统计逆序对数目 j += 1 k += 1 # 将左侧剩余元素填入临时数组 while i <= mid: temp_arr[k] = arr[i] i += 1 k += 1 # 将右侧剩余元素填入临时数组 while j <= right: temp_arr[k] = arr[j] j += 1 k += 1 # 把临时数组的内容复制回原数组 for loop_var in range(left, right + 1): arr[loop_var] = temp_arr[loop_var] return inv_count def _mergeSort(arr, temp_arr, left, right): inv_count = 0 if left < right: mid = (left + right) // 2 inv_count += _mergeSort(arr, temp_arr, left, mid) inv_count += _mergeSort(arr, temp_arr, mid + 1, right) inv_count += merge_and_count(arr, temp_arr, left, mid, right) return inv_count % 1000000007 def count_inversions(arr): temp_arr = [0]*len(arr) return _mergeSort(arr, temp_arr, 0, len(arr)-1) # 测试代码 arr = [1, 20, 6, 4, 5] result = count_inversions(arr) print(f"Array contains {result} inversions.") ``` 上述代码实现了基于归并排序的逆序对统计功能,并返回结果对 \(10^9+7\) 取模后的值[^3]。 --- #### 数学分析 如果数组的元素取自集合 \(\{1, 2, 3, ..., n\}\),那么最多可能存在的逆序对出现在完全倒序的情况下。此时,任意两个位置上的元素都会构成一个逆序对。总共有 \(\frac{n(n-1)}{2}\) 对这样的组合[^2]。 例如: - 当 \(n=4\) 时,最大逆序对数为 \(\frac{4(4-1)}{2}=6\); - 当 \(n=5\) 时,最大逆序对数为 \(\frac{5(5-1)}{2}=10\)。 这种情况下,数组的形式应为 \([n, n-1, ..., 1]\)。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值