Ultra-QuickSort (线段树求逆序数+离散化)

Posted 1013star

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ultra-QuickSort (线段树求逆序数+离散化)相关的知识,希望对你有一定的参考价值。

Ultra-QuickSort

 OpenJ_Bailian - 2299 

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.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 (线段树求逆序数+离散化)的主要内容,如果未能解决你的问题,请参考以下文章

hdu6318 离散化+线段树求逆序数

线段树求逆序对

HDU - 1394 Minimum Inversion Number(线段树求逆序数---点修改)

权值线段树求逆序对问题

POJ 2299 Ultra-QuickSort(线段树+离散化)

POJ 2299 -Ultra-QuickSort-树状数组求逆序数