Ultra-QuickSort POJ - 2299 (树状数组)

Description

Ultra-QuickSort POJ - 2299 (树状数组)_第1张图片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

树状数组模板题。
思路:看此篇博文之前,你要对树状数组有所了解,这里树状数组求的也是和,并且因为更新多次,所以不用树状数组减少复杂度的话 铁定超时。
树状数组主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值; 经过简单修改可以
在log(n)的复 杂度下 进行范围修改;而这道题意思是每一项之前有多少大于等于它的。
把样例换一个角度看,就把他们一个一个输入,例如第一组样例:输入9时,前面没有比它大的,不必交换,
输入1时, 前面有个9,需要交换一次,变成1,9;输入0时,需要交换两次,先是0和9 交换,成1,0,9,再
0和1交换,0,1,9;
依次类推,计算最小交换次数,所以等于变相的求每一项前面存在几个大于它的数。
再附上 逆序数 的概念:
也就是说,对于n个不同的元素,先规定各元素之间有一个标准次序(例如n个 不同的自然数,可规定
从小到大为标准次序),于是在这n个元素的任一排列中,当某两个元素的先后次序与标准次序不同时
,就说有1个逆序。一个排列中所有逆序总数叫做这个排列的逆序数。
而这道题,你会发现,至少交换多少次就是找这个排列有多少逆序数。
就拿样例来说吧:规定是从小到大排列,对于排列 9 1 0 5 4;所以这个排列应该是递增的。
所以,对于9来说,前面没有比它大的,也就是9的逆序数是0,对于1,前面有一个比他大,所以
1的逆序数是1,以此类推,0的逆序数是2,5的是1,4的是2.而对于这个排列来说,逆序数等于各个数
的逆序数的和,也就是6.
代码:
#include
#include
#include
#include
using namespace std;
int n;
struct pp
{
    int v,x;
} a[500003];
bool cmp(pp a,pp b)
{
    return a.v



你可能感兴趣的:(ACM竞赛,【数据结构】--树状数组,ACM的进程)