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

poj 2299 Ultra-QuickSort

2017-04-10 14:43 232 查看
Description


In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements
until the sequence is sorted in ascending order. For the input sequence
9 1 0 5 4 ,

Ultra-QuickSort produces the output
0 1 4 5 9 .

Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.

Input
The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999,
the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.
Output
For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.
Sample Input
5
9
1
0
5
4
3
1
2
3
0

Sample Output
6
0
题意:就是说冒泡排序的时候的交换次数是多少。
思路:用树状数组,先把数据离散化一下,节省内存,为什么要用离散化呢,如果告诉你数据范围是10^9,数据量是10^4没法开那么大的数组,离散化之后,只需要开10^4
大小的数组就行了,然后按照初始位置放到树状数组里,进行计算就行了,因为不是区间求和,树状数组C标记为1,即代表此数已经放进树状数组里了。放进数组里之后判断
比其小的数是否已经在里面了,确定排序时移动的次数(实在不明白的话,先搞懂树状数组,然后手动模拟代码)。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n;
int c[500005];
int reflect[500005];
struct node {
int p;
int num;
} a[500005];
int cmp(node x,node y) {
return x.num < y.num;
}
int lowbit(int x) {
return x&(-x);
}
void build(int p,int num) {
while(p<=n) {
c[p]+=num;
p+=lowbit(p);
}
}
int sum(int x) {
int ans=0;
while(x>0) {
ans+=c[x];
x-=lowbit(x);
}
return ans;
}

int main() {
int i;
while(scanf("%d",&n)!=EOF && n) {
for(i=1; i<=n; i++) {
scanf("%d",&a[i].num);
a[i].p=i;//记录这个数据的初始位置
}
sort(a+1,a+1+n,cmp);//排序的目的就是为了方便进行离散化
memset(c,0,sizeof(c));
for(i=1; i<=n; i++) {
reflect[a[i].p]=i;//离散化,为了节省空间(因为开树状数组是根据数的大小开的数组)
}

long long ans=0;
for(i=1; i<=n; i++) {
build(reflect[i],1);
ans+=i-sum(reflect[i]);//判断放进去以后 比其小的数有没有被放进来,从而得到要换多少次
}
printf("%lld\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM