基础算法4——归并排序拓展:求逆序对数量

* 拓展:求逆序对数量

subject:
给定长度为n的数组(1≤n≤100000)(数列中的元素的取值范围 [1,1e9]),若i<j,a[i]>a[j],则为逆数对。

步骤: 1)确定分点:mid=(l+r)/2; 2)数列分为[l,mid]&[mid+1,r] ∴逆序对的出现分为三种情况:a.两数在[l.mid]内; b.两数在[mid+1,r]内; c.两区间各一数。 :两区间内数的顺序与c情况无关,∴可以单独处理完a和b情况后递归排序,方便c的处理。 3)情况a,递归算左边; 4)右边排序; 5)情况b,递归算右边; 6)左边排序; 7)情况c,依次比较两数列的数,直到找到a[i]>a[j],则第一个数列中i后的数都>a[j], ∴ans+=mid-i+1;

eg.
#include<stdio.h>
​
long long q[100009], t[100009],ans;
​
void merge_sort(long long q[],int l, int r)
{
     int mid = (l + r) / 2,i=l,j=mid+1,k=0;
     while (l >= r)return;
     merge_sort(q,l, mid);
     merge_sort(q,mid + 1, r);
     while (i <=mid&&j<=r)
     {
          if (q[i] <= q[j])
          {
               t[k++] = q[i++];
          }
          else
          {
               t[k++] = q[j++];
               ans+=(mid-i+1);
          }
     }
     while (i <= mid)t[k++] = q[i++];
     while (j <= r)t[k++] = q[j++];
     for (i = l, j = 0; i <= r; i++, j++)
     {
          q[i] = t[j];
     }
}
​
int main()
{
     int n,i;
     scanf("%d", &n);
     for (i = 0; i < n; i++)
     {
          scanf("%lld", &q[i]);
     }
     merge_sort(q,0, n - 1);
     printf("%lld", ans);
     return 0;
}
​
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值