—— by A Code Rabbit
Description
输入一个序列,求序列的逆序数。
Type
Merge Sort
Advanced Data Structures :: Segment Tree
Advanced Data Structures :: Binary Indexed Tree
Analysis
求逆序数,用树状数组来做。
不过求逆序数的题目按惯例说应该用归并排序比较正宗。
况且这道题用树状数组还需要离散化,离散化也需要排序……
有点多此一举。
那么树状数组的好处是什么?我们为什么选择树状数组呢?
答案是,为了套模板……
Solution
// POJ 2299
// Ultra-QuickSort
// by A Code Rabbit
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 500002;
struct Bit {
int c[MAXN], n;
void Init(int x) { memset(c, 0, sizeof(c)); n = x; }
void Add(int x, int y) {
while (x <= n) { c[x] += y; x += x & -x; }
}
int Sum(int x) {
int res = 0;
while (x > 0) { res += c[x]; x -= x & -x; }
return res;
}
};
struct Element {
int val;
int order;
bool operator<(Element one) const { return val > one.val; }
};
int n;
Element a[MAXN];
Bit bit;
int main() {
while (scanf("%d", &n) && n) {
for (int i = 0; i < n; i++) {
scanf("%d", &a[i].val);
a[i].order = i;
}
sort(a, a + n);
int rank[MAXN];
for (int i = 0; i < n; i++) {
rank[a[i].order] = i + 1;
}
long long ans = 0;
bit.Init(n);
for (int i = 0; i < n; i++) {
ans += bit.Sum(rank[i] - 1);
bit.Add(rank[i], 1);
}
printf("%lld\n", ans);
}
return 0;
}