线段树——Ultra-QuickSort

时间:2021-10-25 17:18:58

题目网址:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=109331#problem/A

Description

线段树——Ultra-QuickSortIn 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 题意:输入n个数,相邻两个数可以交换位置进行从小到大排序,求最小交换次数。 解题思路:用线段树的思想将数组一半一半的划分成小的区间,最后划分为只有两个数的区间,这两个数进行比较交换位置,记录交换次数就。先进行前两个数的比较,然后扩大区间为(left,right),
可知(left,right)区间中,(left,center)和(center+1,right)区间里的数已经排好序,将(center+1,right)中的数一个一个与(left,center)中的数比较大小,用另一个数组记录
新的排序后的位置(相当于向前插入数),并记录交换次数。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;
int a[];
long long num;
int temp[]; void Merge(int arr[], int left, int center, int right)
{
int i=left;
int j=center+;
int k=;
while (i<=center&&j<=right)
{
///可知(left,right)区间中,(left,center)和(center+1,right)区间里的数已经排好序
if (arr[i] > arr[j])
{
temp[k++] = arr[j++];///
num+= center+-i;
}
else
temp[k++] = arr[i++];///记录小的数,以便得到排序后新的序列;
}
while (i <= center) ///
temp[k++] = arr[i++];
while (j <= right) ///这个和上个while语句两个while语句记录了原数组交换次序后的新的数组;
temp[k++] = arr[j++];
for (i = left, k = ; i <= right; i++, k++)///将array[]数组变为新的数组;
arr[i] = temp[k];
} void mergeSort(int arr[], int left, int right)
{
if (left<right)
{
int center = (left + right) / ;
mergeSort(arr, left, center); ///
mergeSort(arr, center + , right);///将数组划分为两个区间;
Merge(arr, left, center, right); ///将这个区间里的数进行排序;
}
} int main()
{
int n;
while(scanf("%d",&n)&&n)
{
num=;
for(int i=;i<n;i++)
scanf("%d",&a[i]);
mergeSort(a,,n-);
printf("%lld\n",num);
}
}