求数列逆序数复杂度O(nlogn)的两种算法
1. 树状数组,对于大数据需要进行离散化处理
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <stack>
#define INF (int)(1e9)
#define maxn 1000010
#define Lson l, mid, rt << 1
#define Rson mid + 1, r, rt << 1 | 1
using namespace std;
typedef long long ll;
struct node {
int x, v;
bool operator < (const node &g) const {
if (x != g.x) return x < g.x;
return v > g.v;
}
}no[maxn];
int num[maxn << 1], n;
int lowbit(int x) {return x&(-x);}
void update(int x, int v) {
for (; x <= maxn; x += lowbit(x)) {
num[x] += v;
}
}
ll query(int x) {
ll ret = 0;
for (; x > 0; x -= lowbit(x)) {
ret += ll(num[x]);
}
return ret;
}
int main() {
while (scanf("%d", &n) != EOF) {
memset(num, 0, sizeof(num));
for (int i = 1; i <= n; ++ i) {
scanf("%d%d", &no[i].x, &no[i].v);
}
sort(no+1, no+n+1);
ll res = 0;
for (int i = 1; i <= n; ++ i) {
update(no[i].v,1);
res += (i - query(no[i].v));
}
printf("%lld\n", res);
}
}
2. 归并排序同时求出逆序数
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <stack>
#define INF (int)(1e9)
#define maxn 1000010
#define Lson l, mid, rt << 1
#define Rson mid + 1, r, rt << 1 | 1
using namespace std;
typedef long long ll;
struct P {
int a,b;
} s[1100005],t[1100005];
bool cmp (P a, P b) {
if (a.a != b.a) return a.a < b.a;
return a.b > b.b;
}
ll ans;
void merge_sort(P* A, int x, int y, P *T) {
if (y - x > 1) {
int m = (y + x) >> 1;
int p = x, q = m, i = x;
merge_sort(A, x, m, T);
merge_sort(A, m, y, T);
while (p < m || q < y) {
if(q >= y || (p < m && A[p].b <= A[q].b)) {
T[i++] = A[p++];
} else {
T[i++] = A[q++];
ans += ll(m-p);
}
}
for (i = x; i < y; i ++)
A[i] = T[i];
}
}
int main() {
int n;
while (cin >> n) {
memset(s, 0, sizeof(s));
memset(t, 0, sizeof(t));
for(int i = 0; i < n; ++ i) {
scanf("%d%d", &s[i].a, &s[i].b);
}
sort(s, s+n, cmp);
ans = 0;
merge_sort(s, 0, n, t);
cout << ans << endl;
}
return 0;
}