求逆序对方法有两种:
树状数组和归并排序,还有暴力
暴力就是两个for循环判断当i<j时,若a[i]>a[j],则ans++;
这里先说归并排序吧,在另一篇博客中再讲树状数组求逆序对(实际上是我写树状数组的还有bug没找到.......)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100005;
int a[N],tmp[N];
long long ans;
void merg_sort(int l, int m, int r)
{
int i=l;
int j=m+1;
int k=l;
while(i<=m&&j<=r)
{
if(a[i]>a[j]) //左边的比右边的大时;
{
tmp[k++]=a[j++];
ans += (m+1-i); //计算逆序数;
}
else tmp[k++]=a[i++]; //右边的比左边的大时;
}
while(i<=m) tmp[k++]=a[i++]; //左边有多余时;
while(j<=r) tmp[k++]=a[j++]; //右边有多余时;
for(int i=l; i<=r; i++)
{
a[i] = tmp[i]; //排序后重新赋值给a;
}
}
void merg(int l, int r)
{
if(l<r)
{
int m=(l+r)>>1;
merg(l, m);
merg(m+1, r);
merg_sort(l, m, r);
}
}
int main()
{
int n;
while(~scanf("%d", &n))
{
for(int i=0; i<n; i++)
{
scanf("%d", &a[i]);
}
ans=0;
merg(0, n-1);
printf("%lld\n", ans);
}
}