归并排序求逆序对 题解

https://www.luogu.org/problemnew/show/P1774

题解

分析

本题要求求交换次数,因为最优方案每交换一次必定消去且仅消去一个逆序对,所以交换次数等于逆序对数,故本题其实就是求逆序对数。

代码

让我贴上我丑陋的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
int n;
int a[1055155];
int c[1000155];
long long ans;
void (int x,int y)
{
if(x==y)
return;
int mid=(x+y)/2;
merge(x,mid);
merge(mid+1,y);
int cnt=x;
int i=x;
int j=mid+1;
while(i<=mid&&j<=y)
{
if(a[i]<=a[j])
{
c[cnt++]=a[i++];
}
else
{
c[cnt++]=a[j++];
ans+=mid-i+1;
}
}
while(i<=mid)
c[cnt++]=a[i++];
while(j<=y)
c[cnt++]=a[j++];
for(int i=x;i<=y;i++)
a[i]=c[i];
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
merge(1,n);
cout<<ans<<endl;
return 0;
}