poj2299 Ultra-QuickSort 二叉排序树或树状数组

escription

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
 
题目大意就是求出用冒泡排序时需要交换几次,那么我选择二叉排序树。
 
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
struct bitree{
	int num,cnt;
	struct bitree *lchild,*rchild;
};
long long s;
bitree *build(int n)
{
	bitree *leaf=new bitree;
	leaf->num=n;
	leaf->cnt=0;
	leaf->lchild=leaf->rchild=NULL;
	return leaf;
}
void insert(bitree *&root,int n)
{
	if(root==NULL)root=build(n);
	else if((root->num)>n)
	{
		s+=root->cnt+1;
		insert(root->lchild,n);
	}
	else {
		root->cnt++;
		insert(root->rchild,n);
	}
}
int main()
{
	int n,x;
	while(scanf("%d",&n)!=EOF&&n)
	{
		s=0;
		bitree* root=NULL;
		while(n--)
		{
			scanf("%d",&x);
			insert(root,x);
		}
		printf("%I64d\n",s);
	}
	return 0;
}


这是树状数组的,需要离散化.
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
#define lowbit(i) ((-i)&i)
struct node{
	int v,ord;
}in[500010];
int a[500010],e[500010],n;
bool cmp(node a,node b)
{
	return a.v<b.v;
}
void add(int x)
{
	while(x<=n){
		e[x]++;
		x+=lowbit(x);
	}
}
void scan(int x)
{
	scanf("%d",&in[x].v);
	in[x].ord=x;
}
int sum(int x)
{
	int s=0;
	while(x>0)
	{
		s+=e[x];
		x-=lowbit(x);
	}
	return s;
}
int main()
{
	while(~scanf("%d",&n),n)
	{
		int i;
		for(i=1;i<=n;i++)scan(i);
		sort(in+1,in+1+n,cmp);
		for(i=1;i<=n;i++)a[in[i].ord]=i;
		memset(e,0,sizeof(e));
		long long ans=0;
		for(i=1;i<=n;i++)
		{
			add(a[i]);
			ans+=i-sum(a[i]);
		}
		printf("%lld\n",ans);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值