题目描述
我们部门要排队唱歌,大家乱哄哄的挤在一起,现在需要按从低到高的顺序拍成一列,但每次只能交换相邻的两位,请问最少要交换多少次
输入描述:
第一行是N(N<50000),表示有N个人 然后每一行是人的身高Hi(Hi<2000000,不要怀疑,我们以微米计数),持续N行,表示现在排列的队伍
输出描述:
输出一个数,代表交换次数。
示例1
输入
复制
6 3 1 2 5 6 4
输出
复制
4
题解:求出数组中有多少个逆序对就可以求出要交换多少次,利用树状数组求逆序对。
#include <bits/stdc++.h>
using namespace std;
const int N = 2000000 + 10;
int h[N];
int lowbit(int x){
return (x & (-x));
}
void add(int x){
while(x < N){
h[x] += 1;
x += lowbit(x);
}
}
int query(int x){
int val = 0;
while(x > 0){
val += h[x];
x -= lowbit(x);
}
return val;
}
int main() {
int n;
scanf("%d", &n);
vector<int> a(n);
for (int i = 0; i < n; i++){
scanf("%d", &a[i]);
}
int ans = 0;
reverse(a.begin(), a.end());
for (int i = 0; i < n; i++){
ans += query(a[i] - 1);
add(a[i]);
}
cout << ans << "\n";
return 0;
}