求逆序数----归并排序的实质

本文介绍了一种利用归并排序算法求解数组中逆序数总和的方法。通过对数组进行分治处理,在合并阶段计算逆序数的同时完成排序。此方法适用于竞赛编程中的逆序数相关问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=117

解题思路:所谓逆序就是当前位置的数前面有几个大于这个数,并且这个数与前面数的顺序无关。

    归并排序过程中,将序列分为左右两个进行分治,而且是先对左边进行排序。

    将左序列中小于右序列中的数填入新序列中,每次遇到右边数小于左边数的时候,总是累计左边数的数量,这样求出的就是所有逆序数的和了。并且如果建立一个逆序数数组们可以得到每个数的逆序数。

01. #include<iostream>
02. #include<stdio.h>
03. using namespace std;
04. int  a[1000010];
05. int b[1000010];
06. long long sum=0;
07. void marge(int *a,int beg,int end,int *b){
08. if(beg==end)return;
09. int mid=(beg+end)/2;
10. marge(a,beg,mid,b);
11. marge(a,mid+1,end,b);
12. int i=beg,j=mid+1,pos=beg;
13. while(i<=mid&&j<=end){
14. while(a[i]<=a[j]&&i<=mid)
15. b[pos++]=a[i++];
16. while(a[j]<a[i]&&j<=end){
17. b[pos++]=a[j++];
18. sum+=mid+1-i;
19. }
20. }
21. while(i<=mid)b[pos++]=a[i++];
22. while(j<=end)b[pos++]=a[j++];
23. for(int i=beg;i<=end;i++)
24. a[i]=b[i];//回写到a中  
25. }
26. int main()
27. {
28. int n;cin>>n;
29. while(n--){
30. sum=0;
31. int m;cin>>m;
32. for(int i=1;i<=m;i++)
33. scanf("%d",&a[i]);
34. marge(a,1,m,b);
35. printf("%lld\n",sum);
36. }
37. return 0;
38. }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值