接着上文说
离散化
for (int i = 1; i <= n; i ++) {
cin >> a[i].val;
a[i].id = i;
}
sort(a + 1, a + n + 1); //定义结构体时按val从小到大重载
for (int i = 1; i <= n; i ++)
b[a[i].id] = i; //将a[i]数组映射成更小的值,b[i]就是a[i]对应的rank(顺序)值
for (int i = 1; i <= n; i ++) {
scanf("%d",&num[i]);
lsh[i] = num[i]; //复制一份原数组
}
sort(lsh + 1, lsh + n + 1); //排序,unique虽有排序功能,但交叉数据排序不支持,所以先排序防止交叉数据
//cnt就是排序去重之后的长度
cnt = unique(lsh + 1, lsh + n + 1) - lsh - 1; //unique返回去重之后最后一位后一位地址 - 数组首地址 - 1
for (int i = 1; i <= n; i++)
num[i] = lower_bound(lsh + 1, lsh + cnt + 1, num[i]) - lsh;
代码+解释
#include <cstdio>
#include <algorithm>
using namespace std;
const int M = 1e3 + 5;
int a[M], dis[M], bit[M];
int n;
void Read() {
scanf("%d", &n);
for (int i = 1; i <= n; i ++) {
scanf("%d", &a[i]);
}
}
void Discretetion() {
for (int i = 1; i <= n; i ++) {
dis[i] = a[i];
}
sort(dis + 1, dis + 1 + n);
int len = unique(dis + 1, dis + 1 + n) - dis - 1;
for (int i = 1; i <= n; i ++) {
a[i] = lower_bound(dis + 1, dis + 1 + n, a[i]) - dis;
}
}
int lowbit(int x) { return x & (- x); }
void update(int k) {
for (int i = k; i <= n; i += lowbit(i)) {
bit[i] ++; //从之前的修改值,变为增加一次
}
}
int Sum(int k) {
int tot = 0;
for (int i = k; i > 0; i -= lowbit(i)) {
tot += bit[i];
}
return tot;
}
void work() {
int ans = 0;
for (int i = 1; i <= n; i ++) {
update(a[i]); //因为逆序对需要保证下标按顺序,所以必须放一个,求一次
ans += i - Sum(a[i]); //累加
}
printf("%d", ans);
}
int main() {
Read(); //输入
Discretetion(); //离散化
work(); //输出
return 0;
}