Беси сделала гибрид из двух любимых алгоритмов
пузырьковой сортировки и быстрой сортировки:
Назовём позицию между элементами \(i\) и \(i+1\) массива \(A\) точкой разбиения
если максимум из \(A[...i]\) не больше чем минимум \(A[i+1 \ldots]\).
Беси помнит, что быстрая сортировка реорганизует массив так, чтобы у него
появилась точка разбиения, а затем рекурсивно сортирует две стороны
\(A[...i]\) и \(A[i+1 \ldots]\). Однако хотя она помнит, что все точки разбиения
можно найти за линейное время, она забыла как в быстрой сортировке
реорганизуется массив, чтобы быстро создать точку разбиения.
Она решила использовать пузырьковую сортировку для решения этой задачи
Ниже приведен алгоритм Беси
Сначала она написала простую функцию, которая делает один проход
пузырьковой сортировки:
bubble_sort_pass (A) {
for i = 0 to length(A)-2
if A[i] > A[i+1], swap A[i] and A[i+1]
}
Рекурсивный код Беси для "быстрой" сортировки такой:
quickish_sort (A) {
if length(A) = 1, return
do { // Main loop
work_counter = work_counter + length(A)
bubble_sort_pass(A)
} while (no partition points exist in A)
divide A at all partition points; recursively quickish_sort each piece
}
Теперь Беси интересно, насколько быстро работает её код.
Для простоты она считает, что её итерация работает линейно и поэтому она просто
инкрементирует глобальную переменную work_counter внутри цикла текущим
размером массива так, чтобы оценивать общую работу, выполненную алгоритмом.
По заданному входному массиву, предскажите финальное значение величины
work_counter после завершения алгоритма quickish_sort.
ФОРМАТ ВВОДА (файл sort.in):
Первая строка ввода содержит \(N\) (\(1 \leq N \leq 100,000\)). Следующие
\(N\) строк описывают \(A[0] \ldots A[N-1]\), каждый из которых является
целым числом в интервале \(0 \ldots 10^9\). Не гарантируется, что все элементы
различны.
ФОРМАТ ВЫВОДА (файл sort.out):
Выведите конечное значение величины work_counter
Примеры
| № | Входные данные | Выходные данные |
|
1
|
7 20 2 3 4 9 8 7
|
12
|