Description
A well known algorithm called heapsort is a deterministic sorting algorithm taking O(n log n) time and O(1) additional memory. Let us describe ascending sorting of an array of different integer numbers. The algorithm consists of two phases. In the first phase, called heapification, the array of integers to be sorted is converted to a heap. An array a[1 . . . n] of integers is called a heap if for all 1 <= i <= n the following heap conditions are satisfied:
- if 2i <= n then a[i] > a[2i];
- if 2i + 1 <= n then a[i] > a[2i + 1].
Input
Input contains n (1 <= n <= 50 000).
Output
Output the array containing n different integer numbers from 1 to n, such that it is a heap, and when converting it to a sorted array, the total number of exchanges in sifting operations is maximal possible. Separate numbers by spaces.
题目大意:构造一个大根堆,使得用这个大根堆从小到大排序的时候交换次数最多。
思路:对于一个n个元素的大根堆,交换1和n,然后进行调整(即交换)。为了交换次数最多,我们希望它能交换到最底层,那个数当然最好是1。然后为了保证深度最大(有可能左边的深度比左边大1),那么我们希望顶元素1调整到n-1的位置。于是开始递推,对于 i-1 个元素最大的情况,最后一位是1,那么我们把1调整到最顶端。然后顶端置 i ,第 i 位置1。那么,我们进行排序到剩下 i 个元素的时候,顶端和位置n交换,剩下 i-1个元素,就必然需要把顶端的1调整到 i-1 的位置。因为我们把1往上调整的时候,比如要把x = heap[j/2]移动到heap[j],那么当1调整到j/2的时候,x肯定是j/2比较大的儿子(因为另一个儿子曾经是x的儿子)。
PS:我用G++交TLE了从C++交AC了你们看着办吧……
代码(391MS):
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 typedef long long LL; 7 8 const int MAXN = 50010; 9 10 int heap[MAXN]; 11 12 int main() { 13 int n; 14 while(scanf("%d", &n) != EOF) { 15 heap[1] = 1; 16 for(int i = 2; i <= n; ++i) { 17 for(int j = i - 1; j != 1; j >>= 1) { 18 heap[j] = heap[j >> 1]; 19 } 20 heap[1] = i; 21 heap[i] = 1; 22 } 23 for(int i = 1; i < n; ++i) printf("%d ", heap[i]); 24 printf("%d ", heap[n]); 25 } 26 }