题目描述
在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。比如一个序列为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;
}