目录
一.题目
题目描述
设A[1..n]是一个包含N个数的数组。如果在i〈 j的情况下,有A[i] 〉a[j],则(i,j)就称为A中的一个逆序对。 例如,数组(3,1,4,5,2)的“逆序对”有 <3,1>,<3,2>,<4,2>,<<5,2> 共4个。 使用 归并排序 可以用O(nlogn)的时间解决统计逆序对个数的问题 。
输入
第1行:1个整数N表示排序元素的个数。(1≤N≤100000) 第2行:N个用空格分开的整数,每个数在小于100000。
输出
1行:仅一个数,即序列中包含的逆序对的个数。
样例输入
3
1 3 2
样例输出
1
题解
这是一道十分简单的树状数组引入题目。相信大家一定都做过逆序对吧,首先来看二路归并的代码:
二路归并
十分简单,只要会二分排序,那么就一定会这道题:
代码如下:
#include <cstring>
#include <cstdio>
#define M 100005
int n, a[M], b[M], c[M];
long long ans;
inline void bing(int l, int mid, int r){
int k = l, k1 = mid + 1, k2 = l;
while(k <= mid && k1 <= r){
if(a[k] <= a[k1])
b[k2 ++] = a[k ++];
else{
ans = ans + mid - k + 1;
b[k2 ++] = a[k1 ++];
}
}
while(k <= mid)
b[k2 ++] = a[k ++];
while(k1 <= r)
b[k2 ++] = a[k1 ++];
for(int i = l; i <= r; i ++)
a[i] = b[i];
}
inline void fen(int l, int r){
int mid = (l + r) / 2;
if(l >= r)
return ;
fen(l, mid);