POJ Problem 2299 - Ultra-QuickSort
题目类型:树状数组、逆序数、离散化
题意
给定一个序列,求出其中逆序数的个数。
分析
可以使用归并排序来求也可以使用树状数组来求,结果记得使用 l o n g long long。在用树状数组求得时候需要使用离散化。
代码
static int[] a;
static int[] C;
static int[] all;
static int aLen;
public static void solve() throws IOException {
while (true) {
int n = nextInt();
if (n == 0) return ;
init(n);
for (int i = 1; i <= n; i++) a[i] = nextInt();
System.arraycopy(a, 1, all, 1, n);
aLen = unique(all, 1, aLen);
long ans = 0;
for (int i = 1; i <= n; i++) {
int x = getAim(all, 1, aLen, a[i]);
add(x, 1, n);
ans += i - getSum(x);
}
pw.println(ans);
}
}
public static int getAim(int[] arr, int l, int r, int aim) {
while (l < r) {
int mid = l + r >> 1;
if (arr[mid] >= aim) r = mid;
else l = mid + 1;
}
return r;
}
public static int unique(int[] all, int l, int r) {
Arrays.sort(all, l, r);
if (r - l == 0) return 0;
int q = 2, p = 2;
while (p < r) {
if (all[q - 1] != all[p]) all[q++] = all[p];
p++;
}
return q;
}
public static void add(int x, int v, int n) {
while (x <= n) {
C[x] += v;
x += lowbit(x);
}
}
public static int getSum(int x) {
int re = 0;
while (x > 0) {
re += C[x];
x -= lowbit(x);
}
return re;
}
public static int lowbit(int x) { return x & (-x); }
public static void init(int n) {
aLen = n + 1;
a = new int[n + 1];
C = new int[n + 1];
all = new int[n + 1];
}