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

poj2299Ultra-QuickSort【线段树求逆序数】离散化

2016-03-15 16:48 531 查看
Ultra-QuickSort

Time Limit: 7000MS Memory Limit: 65536K
Total Submissions: 52097 Accepted: 19113
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

Source
Waterloo local 2005.02.05

之前写过求逆序数的树状数组的方法和归并排序的方法

poj2299Ultra-QuickSort【树状数组求逆序数、离散化】、【归并排序模板】

感觉逆序数这玩意就应该用归并排序做啊~~

说线段树的方法:与上一篇

poj2352Stars【线段树单点更新区间求和】

相似的是,都是单点更新区间求和,而且从自身到根节点这一路一直++。不同的是,之前那个题是求前一部分的和,这个要求后一部分的值,这我就不理解了,逆序数明明等于N-[1,i]的值啊,为啥查询的时候只需要求[i+1,n]?好好想想:区间[1,i]的值+区间[i+1,N]的值=区间[1,N]的值(i已经标记为1),所以区间[i+1,N]值的总和等于N-[1,i]的值!因为总共有N个数,不是比它小就是比它(大或等于)。……

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 500005
struct node
{
int id,val;
}num[maxn];
bool cmp(node n1,node n2)
{
return n1.val<n2.val;
}
struct Tree
{
int l,r,tot;
}tree[maxn<<2];
int rank[maxn];
void build(int rt,int l,int r)
{
tree[rt].l=l;tree[rt].r=r;
tree[rt].tot=0;
if(l==r)return;
int mid=(l+r)/2;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
}
void update(int rt,int x)
{
tree[rt].tot++;
if(tree[rt].l==tree[rt].r&&tree[rt].l==x)
return;
int mid=(tree[rt].l+tree[rt].r)/2;
if(x<=mid)update(rt<<1,x);
else update(rt<<1|1,x);
}
int query(int rt,int l,int r)
{
int sum=0;
if(tree[rt].l==l&&tree[rt].r==r)
return tree[rt].tot;
int mid=(tree[rt].l+tree[rt].r)/2;
if(r<=mid) sum=query(rt<<1,l,r);
else if(l>mid) sum=query(rt<<1|1,l,r);
else
sum=query(rt<<1,l,mid)+query(rt<<1|1,mid+1,r);
return sum;
}
int main()
{
// freopen("cin.txt","r",stdin);
int n;
while(~scanf("%d",&n)&&n)
{
for(int i=0;i<n;i++)
{
scanf("%d",&num[i].val);
num[i].id=i;
}
sort(num,num+n,cmp);
for(int i=0;i<n;i++) rank[num[i].id]=i+1;
build(1,0,n+1);
long long sum=0;
for(int i=0;i<n;i++)
{
int x = rank[i];
sum+=query(1,x+1,n+1);
update(1,x);
}
printf("%I64d\n",sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: