【POJ】【P2299】【Ultra-QuickSort】【题解】【求逆序对】

传送门:http://poj.org/problem?id=2299

题意:求逆序对数

题解:离散化+树状数组求逆序对

1.其实这道题还可以用归并排序写,蒟蒻还是觉得树状数组好些一点……

2.离散化,是因为数据范围给到了999999999,数组开不出来,于是把每个数建立一个映射,通常就用排序后的index做映射离散化

3.n^2算法是冒泡排序,优化成为归并排序,或者枚举每个数在位置和数值都比它小的个数,求和可以用树状数组优化为nlogn

/*
	ID:iamzky
	OJ:POJ
	Index:2299
	Language:C++
*/
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct num{
	int X,Y;
};
bool cmp(num a,num b){
	return a.X<b.X;
}
num a[500010];//原数组 
int b[500010];//离散后的数组 
int d[500010];//bit数组 
int n;
inline int lowbit(int x){
	return x&(-x);
}
int get(int x){
	int s=0;
	while(x){
		s+=d[x];
		x-=lowbit(x);
	}
	return s;
}
void updata(int x){
	while(x<=n){
		d[x]++;
		x+=lowbit(x);
	}
}
int main(){
	int i;
	while(cin>>n){
		if(!n)break;
		for(i=1;i<=n;i++){
			cin>>a[i].X;
			a[i].Y=i;
		}
		sort(a+1,a+1+n,cmp);
		for(i=1;i<=n;i++){
			b[a[i].Y]=i;//离散化,自己好好想想为什么 
		}
		memset(d,0,sizeof(d));//别忘了清空哦,蒟蒻因为它WA了3次 
		long long ans=0;
		for(i=1;i<=n;i++){
			updata(b[i]);
			ans+=(i-get(b[i]));
		}
		cout<<ans<<endl;
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值