逆序對的數量 - 題解

Jerrycyx發表於2024-07-27

逆序對的數量

時間限制:C/C++ 1000MS,其他語言 2000MS
記憶體限制:C/C++ 64MB,其他語言 128MB

描述

給定一個長度為 \(n\) 的整數數列,請你計算數列中的逆序對的數量。
逆序對的定義如下:對於數列的第 \(i\) 個和第 \(j\) 個元素,如果滿足 \(i<j\)\(a[i]>a[j]\),則其為一個逆序對;否則不是。
資料範圍 \(1≤n≤100000\),數列中的元素的取值範圍 \([0,10^9]\)

輸入描述

第一行包含整數 n,表示數列的長度。
第二行包含 n 個整數,表示整個數列。

輸出描述

輸出一個整數,表示逆序對的個數。

用例輸入 1

6
2 3 4 5 6 1

用例輸出 1

5

程式碼

#include<cstdio>
#include<algorithm>
using namespace std;

const int N=1e5+5;
int n,a[N],c[N];
long long ans=0;

void _merge(int l1,int r1, int l2,int r2,int sc)
{
	int p1=l1,p2=l2,p3=sc-1;
	while(p1<=r1 && p2<=r2)
	{
		if(a[p1]<=a[p2])
		{
			c[++p3]=a[p1];
			p1++;
		}
		else
		{
			ans+=(r1-p1+1);
			c[++p3]=a[p2];
			p2++;
		}
	}
	while(p1<=r1) c[++p3]=a[p1], p1++;
	while(p2<=r2) c[++p3]=a[p2], p2++;
	return;
}

void merge_sort(int l,int r)
{
	if(l>=r) return;
	int mid=(l+r)>>1;
	merge_sort(l,mid);
	merge_sort(mid+1,r);
	_merge(l,mid, mid+1,r ,l);
	for(int i=l;i<=r;i++) a[i]=c[i];
	return;
}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	merge_sort(1,n);
	printf("%lld\n",ans);
	return 0;
}

相關文章