题目描述
有一实数序列A[1]、A[2] 、A[3] 、……A[n-1] 、A[n] (n<3000000),若i[HTML_REMOVED]A[j],则称A[i]与A[j]构成了一个逆序对,求数列A中逆序对的个数。
例如,5 2 4 6 2 3 2 6,可以组成的逆序对有
(5 2),(5 4),(5 2),(5 3),(5 2),
(4 2),(4 3),(4 2),
(6 2),(6 3),(6 2),
(3 2)
共:12个
输入格式
共两行,第一行有一个正整数n,第二行有n个整数。
输出格式
只有一行为逆序对个数
样例
样例输入
8
5 2 4 6 2 3 2 6
样例输出
12
C++ 代码
#include<bits/stdc++.h>
using namespace std;
const int N = 3e6+50;
int n, tmp[N], a[N];
long long ans = 0;
//归并排序+求逆序对
//q[]为临时数组
void merge_sort(int q[], int l, int r)
{
if(l >= r) return ;
int mid = (l + r) >> 1; //即为除以2
merge_sort(q, l, mid);
merge_sort(q, mid+1, r);
int k = 0, i = l, j = mid + 1;
while(i <= mid and j <= r)
{
if(q[i] <= q[j]) tmp[k++] = q[i++];
else{
ans += mid - i + 1;
tmp[k++] = q[j++];
}
}
while(i <= mid) tmp[k++] = q[i++];
while(j <= r) tmp[k++] = q[j++];
for(i=l,j=0; i<=r; i++) q[i] = tmp[j++];
}
int main(){
scanf("%d",&n);
for(int i=1; i<=n; i++) scanf("%d",&a[i]);
merge_sort(a, 1, n);
printf("%lld",ans);
return 0;
}