poj 2299 Ultra-QuickSort(树状数组求逆序数+离散化)

时间:2023-03-09 00:39:13
poj 2299 Ultra-QuickSort(树状数组求逆序数+离散化)

题目链接:http://poj.org/problem?id=2299

Description

poj 2299 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 

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

逆序数。

代码例如以下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=500017;
int n;
int aa[maxn]; //离散化后的数组
int c[maxn]; //树状数组 struct Node
{
int v;
int order;
}in[maxn]; int Lowbit(int x) //2^k
{
return x&(-x);
} void update(int i, int x)//i点增量为x
{
while(i <= n)
{
c[i] += x;
i += Lowbit(i);
}
}
int sum(int x)//区间求和 [1,x]
{
int sum=0;
while(x>0)
{
sum+=c[x];
x-=Lowbit(x);
}
return sum;
} bool cmp(Node a ,Node b)
{
return a.v < b.v;
} int main()
{
int i,j;
while(scanf("%d",&n) && n)
{
//离散化
for(i = 1; i <= n; i++)
{
scanf("%d",&in[i].v);
in[i].order=i;
}
sort(in+1,in+n+1,cmp);
for(i = 1; i <= n; i++)
aa[in[i].order] = i;
//树状数组求逆序
memset(c,0,sizeof(c));
__int64 ans=0;
for(i = 1; i <= n; i++)
{
update(aa[i],1);
ans += i-sum(aa[i]);//逆序数个数
}
printf("%I64d\n",ans);
}
return 0;
}