描述
给定一个1-N的排列A1, A2, … AN,如果Ai和Aj满足i < j且Ai > Aj,我们就称(Ai, Aj)是一个逆序对。
求A1, A2 … AN中所有逆序对的数目。
输入
第一行包含一个整数N。
第二行包含N个两两不同整数A1, A2, … AN。(1 <= Ai <= N)
对于60%的数据 1 <= N <= 1000
对于100%的数据 1 <= N <= 100000
输出
一个整数代表答案
样例输入
5
3 2 4 5 1
样例输出
5
思路:
利用归并排序的性质,统计逆序对的个数,还可以用树状数组来做。注意要用 long long
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
const int maxn = 1e5+6;
long long Merge(vector<int> &A,int low , int high,vector<int> tmp)
{
int i = low;
int mid = (low + high) / 2;
int j = mid + 1;
long long cnt = 0;
while ( i <= mid && j <= high) {
if (A[i] > A[j]){
tmp.push_back(A[j++]);
cnt += (long long)mid - i + 1;
}
else
tmp.push_back(A[i++]);
}
while (i <= mid) tmp.push_back(A[i++]);
while (j <= high) tmp.push_back(A[j++]);
for (int i = low,k=0; i<= high && k < tmp.size(); ++i)
A[i] = tmp[k++];
return cnt;
}
long long MergeSort(vector<int> &A, int low, int high)
{ long long left,right,res;
if (low < high) {
int mid = (low + high)/2;
vector<int> tmp;
left = MergeSort(A,low,mid);
right = MergeSort(A,mid+1,high);
res = Merge(A,low,high,tmp);
return res + left + right;
}
else
return 0;
}
int main()
{
int n;
cin >> n;
vector<int>A;
int x;
for (int i = 0; i < n; ++i)
cin >> x,A.push_back(x);
long long res = MergeSort(A,0,n-1);
cout << res << endl;
return 0;
}