题目描述
现在给你一个由n个互不相同的整数组成的序列,现在要求你任意交换相邻的两个数字,使序列成为升序序列,请问最少的交换次数是多少?
输入
输入包含多组测试数据。每组输入第一行是一个正整数n(n<500000),表示序列的长度,当n=0时。
接下来的n行,每行一个整数a[i](0<=a[i]<=999999999),表示序列中第i个元素。
输出
对于每组输入,输出使得所给序列升序的最少交换次数。
样例输入 Copy
5
9
1
0
5
4
3
1
2
3
0
样例输出 Copy
6
0
只是做个笔记该题可以用树状数组做
#include<bits/stdc++.h>
using namespace std;
#define lowbit(i) ((i)&(-i))
const int MAXN=500001;
struct node {
int val;
int pos;
}temp[MAXN];
int n,A[MAXN];
long long c[MAXN];
bool cmp(node a,node b){
return a.val<b.val;
}
void update(int x,int v){
for(int i=x;i<=n;i+=lowbit(i)){
c[i]+=v;
}
}
long long get_sum(int x){
long long sum=0;
for(int i=x;i>0;i-=lowbit(i)){
sum+=c[i];
}
return sum;
}
int main(){
while(~scanf("%d",&n)&&n!=0){
memset(c,0,sizeof(c));
for(int i=0;i<n;i++){
scanf("%d",&temp[i]);
temp[i].pos=i;
}
sort(temp,temp+n,cmp);
for(int i=0;i<n;i++){
A[temp[i].pos]=i+1;
}
long long sum=0;
for(int i=0;i<n;i++){
update(A[i],1);
sum+=get_sum(n)-get_sum(A[i]);
}
printf("%lld\n",sum);
}
return 0;
}