您的位置:首页 > 产品设计 > UI/UE

POJ 2299 && ZOJ 2386 Ultra-QuickSort 线段树

2012-10-02 23:46 459 查看
//POJ 2299 && ZOJ 2386 Ultra-QuickSort 线段树
/*
题意:
给一个序列,序列中的数都不重复,每次可以将序列中的两个数交换,
求将这个序列变成升序序列的最小交换次数

思路:
其实就是求这个序列的逆序数,离散化后边查询边插入即可
注意ans会爆int
*/

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define N 500005

int sum[N<<2],a
,b
;
int n,cnt;
__int64 ans;

int cmp(const void *a,const void *b){
return *(int *)a -*(int *)b;
}

int Bin(int key){
int l = 1,r = cnt,mid;
while(r >= l){
mid = (l + r) >> 1;
if(b[mid] == key) return mid;
if(b[mid] < key) l = mid + 1;
else r = mid-1;
}
return -1;
}

void Build(){
memset(sum,0,sizeof(sum));
}

void Pushup(int rt){
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}

void Update(int rt,int l,int r,int x){
if(l == r){
++sum[rt];
return;
}
int mid = (l + r) >> 1;
if(x <= mid) Update(lson,x);
else		 Update(rson,x);
Pushup(rt);
}

int Query(int rt,int l,int r,int L,int R){
if(L <= l && R >= r){
return sum[rt];
}
int mid = (l + r) >> 1;
int res = 0;
if(L <= mid) res += Query(lson,L,R);
if(R > mid ) res += Query(rson,L,R);
return res;
}

int main(){
int i;
while(scanf("%d",&n),n){
for(i = 1; i <= n; ++i){
scanf("%d",&b[i]);
a[i] = b[i];
}
qsort(b+1,n,sizeof(b[0]),cmp);
cnt = n;
Build();
ans = 0;
for(i = 1; i <= n; ++i){
int x = Bin(a[i]);
ans += Query(1,1,cnt,x,cnt);
Update(1,1,cnt,x);
}
printf("%I64d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: