7-4 逆序对 (14 分)
求逆序对。
输入格式:
第一行是一个整数n,(n<=1000,000)表示输入序列的长度,接下来一行是n个整数(每个数的绝对值小于10
9
)。
输出格式:
一个数,表示逆序对个数(逆序即任意一对数前面的数比后面的数大即为一对逆序对)。
输入样例:
10
1 3 5 7 9 8 4 2 6 10
输出样例:
逆序对对数可能很大,计数器要用long long:
14
说明:样例中如1和3不是逆序对,而3和2是1对逆序对,例子中共有14对逆序对。题目中可能有某些数字出现多次的情况。
#include<stdio.h>
int n;
int a[50001];
long long count;///逆序对的个数 注意 最后结果必须是long long型,并在全局中 ,或者将merge1函数改为 long long 型 最后返回得到的也才是long long型
void merge_sort(int left,int right)
{
int sum=0;
if(left>=right)
return;
int mid=left+(right-left)/2;
int b[right-left+1],idx=0,i=left,j=mid+1;
while(i<=mid&&j<=right)
{
if(a[i]<=a[j])
b[idx++]=a[i++];
else
{
count+=(mid-i+1);
b[idx++]=a[j++];
}
}
while(i<=mid)
b[idx++]=a[i++];
while(j<=right)
b[idx++]=a[j++];
for(i=left,j=0;i<=right&&j<idx;i++,j++)
a[i]=b[j];
}
int merge1(int left,int right)
{
if(left>=right)
return 0;
merge1(left,left+(right-left)/2);
merge1(left+(right-left)/2+1,right);
merge_sort(left,right);
}
int main()
{
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
merge1(1,n);
printf("%lld",count);
}
202204021449六