题目描述
题目分析
该题的答案交换次数与冒泡排序算法的交换次数应该是相同的。由于冒泡排序的时间复杂度为,不适合本题的数据大小。所以我们需要一个更加高效的数据结构。
分析题目,思路每轮是将最小的数字交换至最前,该数字的交换次数即它的位置序号。该数字之前的数字交换次数+1,该数字之后的数字交换次数-1。依次将最小数之前和之后区间的值进行修改过于麻烦,因此引入差分数组,将区间的一次修改时间控制在范围。
我的代码
#include <iostream>
#include <algorithm>
#include <cmath>
#include <map>
using namespace std;
typedef long long ll;
const int max_n = 100003;
multimap<int,int> M; //<k:身高 v:位置 >
int bit[max_n]; //差分数组
int n;
ll sum(int i){
int s = 0;
while(i > 0){
s += bit[i];
i -= i & -i;
}
return s;
}
void add(int i,int x){
while(i <= n){
bit[i] += x;
i += i & -i;
}
}
int main(){
//初始化
cin>>n;
for(int i = 1;i <= n;i++){
int k;
cin>>k;
pair<int,int> P(k,i);
M.insert(P);
bit[i] = 0;
}
//计算
ll ans = 0;
multimap<int,int>::iterator it;
for(it = M.begin();it != M.end();it++){
ll pos = (*it).second;
ans += (pos + sum(pos)) * (pos + sum(pos) - 1) / 2;
add(1,1);
add(pos,-1);
add(pos + 1,-1);
add(n + 1,1);
}
//得到答案
cout<<ans;
return 0;
}