Ultra-QuickSort POJ - 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.

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<stdio.h>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
using namespace std;
typedef long long LL;
const int N=5e5+5;
int n,b[N],c[N];
struct node
{
    int x,y;//x代表值,y代表下标
}a[N];
int cmp(node p,node q)
{
    return p.x<q.x;
}
int lowbit(int i)
{
    return i&(-i);
}
void update(int i,int val)
{
    while(i<=n)
    {
        c[i]+=val;
        i+=lowbit(i);
    }
}
int sum(int i)
{
    int ans=0;
    while(i>0)
    {
        ans+=c[i];
        i-=lowbit(i);
    }
    lowbit(i);
    return ans;
}
int main()
{
    LL ans;
    while(~scanf("%d",&n)&&n)
    {
        ans=0;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i].x);
            a[i].y=i;
        }
        sort(a+1,a+n+1,cmp);
        for(int i=1;i<=n;i++)//离散化
            b[a[i].y]=i;
        for(int i=1;i<=n;i++)
        {
            update(b[i],1);
            ans+=i-sum(b[i]);//已经统计的个数减去小于b[i]的个数就是大于b[i]的数的个数,即逆序数
        }
        printf("%lld\n",ans);
    }
}
/*
离散化:
  x:  9 1 0 5 4
  y:  1 2 3 4 5
下标:1 2 3 4 5
sort以后:
  x:  0 1 4 5 9
  y:  3 2 5 4 1
下标:1 2 3 4 5
离散化后:
 i:  3 2 5 4 1  -->  1 2 3 4 5
b[i]:1 2 3 4 5  -->  5 2 1 4 3
*/

猜你喜欢

转载自blog.csdn.net/Never__give__up/article/details/81413804