POJ_2299_归并排序_统计逆序数

链接: [url]http://poj.org/problem?id=2299[/url]


[img]http://dl.iteye.com/upload/attachment/0062/0967/21554228-854d-37b2-802f-120ba8e02dfb.jpg[/img]

分析:统计给定序列中的逆序数,蛮力法复杂度达O(n^2)会超时,由于归并排序复杂度为O(nlogn)
并且,在排序过程中可以顺便统计逆序数,所以用归并排序可以求出。


注意:在求逆序数时要注意,每当前半部分的数被加入到辅助数组中时,逆序数总数应当增加后半部分已经被添加到辅助数组中的元素的总个数.


#include<stdio.h>
#include<stdlib.h>
//归并排序统计
#define SIZE 500010
int arr[SIZE],T[SIZE];
long long cnt = 0;
void MergeSort(int *A,int *T,int l,int r)
{
if(l==r)
{
return;
}
else
{
int mid = (l+r)/2;
//左右递归
MergeSort(A,T,l,mid);
MergeSort(A,T,mid+1,r);
//merge
int i,j,k;
for(i=l,j=mid+1,k=l;k<=r;)
{
if(i>mid&&j<=r)
{
T[k++] = A[j++];
}
else if(i<=mid&&j<=r&&A[i]>A[j])
{
T[k++] = A[j++];
}
else if(i<=mid&&j<=r&&A[i]<=A[j])
{
T[k++] = A[i++];
cnt+=(j-mid-1);
}
else if(i<=mid&&j>r)
{
cnt+=(j-mid-1);
T[k++] = A[i++];
}
}
for(int i=l;i<=r;i++)
A[i] = T[i];
}
}
int main()
{
int n;
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(scanf("%d",&n),n)
{
for(int i=0;i<n;i++)
{
scanf("%d",&arr[i]);
}
cnt = 0;
MergeSort(arr,T,0,n-1);
printf("%I64d\n",cnt);
}
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值