题目描述
在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。比如一个序列为4 5 1 3 2, 那么这个序列的逆序数为7,逆序对分别为(4, 1), (4, 3), (4, 2), (5, 1), (5, 3), (5, 2),(3, 2)。
输入描述:
第一行有一个整数n(1 <= n <= 100000), 然后第二行跟着n个整数,对于第i个数a[i],(0 <= a[i] <= 100000)。
输出描述:
输出这个序列中的逆序数
示例1
输入
5 4 5 1 3 2
输出
7
思路
在归并排序的基础上稍微修改即可
代码
//逆序数(归并排序)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int n;
ll ans;//1e10
int a[N] , b[N];
void merge(int l , int r)
{
if(l >= r)
return ;
int mid = (l + r) >> 1;
merge(l , mid);
merge(mid + 1 , r);
int i = l , j = mid + 1 , k = l;
while(i <= mid && j <= r)
{
if(a[i] > a[j])
{
ans += mid - i + 1;
b[k++] = a[j++];
}
else
b[k++] = a[i++];
}
while(i <= mid)
b[k++] = a[i++];
while(j <= r)
b[k++] = a[j++];
for(int i = l ; i <= r ; i++)
a[i] = b[i];
}
int main()
{
scanf("%d" , &n);
for(int i = 0 ; i < n ; i++)
scanf("%d" , &a[i]);
merge(0 , n - 1);
printf("%lld\n" , ans);
return 0;
} 
京公网安备 11010502036488号