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

POJ--2299--Ultra-QuickSort

2013-06-28 21:57 274 查看
题目大意:给出一个数字序列,问冒泡排序需要交换数字的次数。

好题啊。。。看着1W多的通过数,以为是水题呢。

解题思路,求出序列中的逆序对数就是需要交换的次数,求逆序对数可以用树状数组求,但是题目给的数据范围略大,需要离散化原来的数据。

所以第一步:先对原来的数据排序,再离散数据,,用1-N 的数表示出各个数字的大小关系就可以了。

第二步:通过树状数组求出逆序对数即可。如果你不知道怎么通过树状数组求逆序对数,那么google一下吧

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define maxn 500200
#define lowbit(x) ((x)&(-(x)))
using namespace std;
struct Num
{
int num;
int pos;
bool operator<(const Num & a)const
{
return num<a.num;
}
}p[maxn];
int n,a[maxn],c[maxn];
void add(int num)
{
while(num<=n)
{
c[num]+=1;
num+=lowbit(num);
}
}
long long sum(int pos)
{
long long res=0;
while(pos>0)
{
res+=c[pos];
pos-=lowbit(pos);
}
return res;
}

bool init()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&p[i].num);
p[i].pos=i;
}
return n;
}
void solve()
{
sort(p,p+n);
for(int i=0;i<n;i++)
{
a[p[i].pos]=i+1;
}
memset(c,0,sizeof(c));
long long ans=0;
for(int i=0;i<n;i++)
{
add(a[i]);
ans+=i-sum(a[i]-1);
}
cout<<ans<<endl;
}

int main()
{
while(init())
solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: