Ultra-QuickSort (线段树求逆序数+离散化)
Posted 1013star
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ultra-QuickSort (线段树求逆序数+离散化)相关的知识,希望对你有一定的参考价值。
Ultra-QuickSort
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
Ultra-QuickSort produces the output
Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.InputThe 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.OutputFor 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
思路:对于每次输入的数据,即刻判断其前面比它大的数的个数,范围是当前这个数+1,到最大值,然后立刻更新。因为数据很大,需要离散化,具体看代码。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e6;
struct node{
int l;
int r;
int sum;
}e[maxn<<2];
struct tree{
int pos;
}tree[maxn<<2];
long long sum;
int mp[maxn];
int a[maxn],n;
void build(int l,int r,int cur)
{
e[cur].l=l;
e[cur].r=r;
e[cur].sum=0;
if(l==r)
return;
int mid=(l+r)/2;
build(l,mid,cur<<1);
build(mid+1,r,cur<<1|1);
}
void pushup(int cur)
{
e[cur].sum=e[cur<<1].sum+e[cur<<1|1].sum;
}
int query(int pl,int pr,int cur)
{
if(pl<=e[cur].l&&e[cur].r<=pr)
{
return e[cur].sum;
}
int mid=(e[cur].l+e[cur].r)/2;
int res=0;
if(pl<=mid)
res+=query(pl,pr,cur<<1);
if(pr>mid)
res+=query(pl,pr,cur<<1|1);
return res;
}
void update(int tar,int cur)
{
if(e[cur].l==e[cur].r)
{
e[cur].sum++;
return;
}
int mid=(e[cur].l+e[cur].r)/2;
if(tar<=mid)
update(tar,cur<<1);
else
update(tar,cur<<1|1);
pushup(cur);
}
int main()
{
while(~scanf("%d",&n)&&n)
{
memset(mp,0,sizeof(mp));
memset(a,0,sizeof(a));
sum=0;
build(1,maxn,1);
int t=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
mp[++t]=a[i];
}
sort(mp+1,mp+t+1);
int cnt=1;
int R;
for(int i=2;i<=t;i++)
{
if(mp[i]!=mp[i-1])
{
mp[++cnt]=mp[i];
}
}
for(int i=1;i<=n;i++)
{
int ul=lower_bound(mp+1,mp+1+cnt,a[i])-mp;
tree[i].pos=ul;
// cout<<ul<<endl;
}
for(int i=1;i<=n;i++)
{
sum+=query(tree[i].pos+1,maxn,1);
update(tree[i].pos,1);
}
printf("%lld
",sum);
}
}
以上是关于Ultra-QuickSort (线段树求逆序数+离散化)的主要内容,如果未能解决你的问题,请参考以下文章
HDU - 1394 Minimum Inversion Number(线段树求逆序数---点修改)