题意:
给出一个排列,要求用题目中的排序算法排序之后,算出每个数所到达的最左端和最右端位置的绝对值之差。
思路:
树状数组,每个数往右移动的距离就是右边比它小的数的个数,而左端点的位置就是初始位置和最终位置的较小值。
代码:
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 111111;
struct BIT {
int n;
int C[MAXN];
void init(int n) {
this->n = n;
memset(C, 0, sizeof(C));
}
int lowbit(int x) {
return x & -x;
}
void add(int x, int y) {
while (x <= n) {
C[x] += y;
x += lowbit(x);
}
}
int sum(int x) {
int res = 0;
while (x > 0) {
res += C[x];
x -= lowbit(x);
}
return res;
}
} bit;
int a[MAXN], l[MAXN], r[MAXN];
int main() {
int T, cs = 0;
scanf("%d", &T);
while (T--) {
int n;
scanf("%d", &n);
bit.init(n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = n; i >= 1; i--) {
r[a[i]] = i + bit.sum(a[i]);
bit.add(a[i], 1);
l[a[i]] = min(i, a[i]);
}
printf("Case #%d:", ++cs);
for (int i = 1; i <= n; i++)
printf(" %d", abs(l[i] - r[i]));
printf("\n");
}
return 0;
}