逆序对的数量 - 题解

逆序对的数量

时间限制: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;
}

前缀和+树状数组 做法

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

inline int read()
{
	int x=0,w=1;char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') w=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=(x<<3)+(x<<1)+(ch^'0');
		ch=getchar();
	}
	return x*w;
}

const int N=5e5+5;
int n;
pair<int,int> a[N];
int b[N],bcnt;
long long ans=0;

long long tree[N];
inline int lowbit(int x){return x&-x;}
inline long long ask(int x)
{
	long long res=0;
	for(;x;x-=lowbit(x)) res+=tree[x];
	return res;
}
inline void add(int x,int y)
{
	for(;x<=n;x+=lowbit(x)) tree[x]+=y;
	return;
}

int main()
{
	n=read();
	for(int i=1;i<=n;i++)
		a[i].first=read(),a[i].second=i;
	sort(a+1,a+n+1);
	a[0].first=-1;
	for(int i=1;i<=n;i++)
	{
		if(a[i].first==a[i-1].first) b[a[i].second]=bcnt;
		else b[a[i].second]=++bcnt;
	}
	for(int i=n;i>=1;i--)
	{
		ans+=ask(b[i]-1);
		add(b[i],1);
	}
	printf("%lld\n",ans);
	return 0;
}
posted @ 2024-07-29 23:23  Jerrycyx  阅读(19)  评论(0编辑  收藏  举报