# 逆序对的两种求法（复习）

## *1. 归并排序

$$T(n)=2T(\frac{n}{2})+f(n)$$

int MergeSort (int l, int r) {
if (l == r) return ;
int mid = (l + r) >> 1;
MergeSort(l, mid), MergeSort(mid + 1, r);
int i = l, j = mid + 1, t = l;
while(i <= mid && j <= r)
if (a[i] <= a[j]) b[t++] = a[i++];
else b[t++] = a[j++];
while(i <= mid) b[t++] = a[i++]; while(j <= r) b[t++] = a[j++];
for(int k = l; k <= r; ++k) a[k] = b[k];
}


else b[t++] = a[j++]


else b[t++] = a[j++], ans += mid - i + 1;//ans为逆序对个数


## *2. 树状数组

$BIT$作为一种巧妙的数据结构，其利用了一种类似于前缀和的思想。通过权值$BIT$来求解逆序对。

#include <cstdio>
#include <algorithm>
typedef long long ll;
using std::sort;

const ll N = 5e5 + 10;
ll n, a[N], b[N], c[N], ans;

inline bool cmp (ll x, ll y) { return a[x] < a[y] || (a[x] == a[y] && x < y); }
inline ll lowbit (ll x) { return x & (-x); }
inline void add (ll x, ll y) { for (; x <= n; x += lowbit(x)) c[x] += y; }
inline ll query (ll x) { ll y = 0; for (; x > 0; x -= lowbit(x)) y += c[x]; return y; }

int main () {
scanf ("%lld", &n);
for (ll i = 1; i <= n; ++i) scanf ("%lld", a + i), b[i] = i;
sort (b + 1, b + n + 1, cmp);
for (ll i = 1; i <= n; ++i) add(b[i], 1). ans += i - query (b[i]);
printf ("%lld\n", ans);
return 0;
}

posted @ 2018-10-18 17:15  water_mi  阅读(767)  评论(0编辑  收藏