Добрый день, на acmp.ru есть такая задача: Подарки
Я пытался решить таким образом:
Если входные данные:
5 10
4 7 4 3 10
Сначало сортировал массив по неубыванию,
3 4 4 7 10
А далее делал так:
while(M > 0)
{
int t = A[1] - A[0];
if(M > t)
{
M -= (t + 1);
A[0] += (t + 1);
}
else
{
A[0] += M;
M = 0;
}
i = 0;
while(A[i] > A[i + 1] && i < N - 1)
swap(A[i], A[i + 1]), i++;
}
А — отсортированный массив
N — кол. элементов массива
M — кол. конфет
Надеюсь по алгоритму, идея решения ясна.. В конце работы алгоритма первый элемент массива и будет ответом.
Но такое решени не эффективное на больших входных данных и получаю TL на 10 тесте.
Теперь хочу попробовать решить через двоичные деревья, т.к. это у меня работает за O(N)
while(A[i] > A[i + 1] && i < N - 1)
swap(A[i], A[i + 1]), i++;
А если сделать через min heap, то будет за O(log N).
У меня возникло 2 вопроса:
1) Как можно реализовать этот min heap самому, что бы там были методы добавления, и удаления корневого элемента? Если у кого есть пример, буду благодарен. В сети не нашел хороших примеров, а сам реализовал совсем не правильно.
2) Как тоже самое сделать через priority_queue? Проблема в том, что по умолчанию этот контейнер в С++ в корневом элементе хранит максимальный элемент, т.е. max heap. А мне нужно наоборот.
Я в справочнике читал, что там ему можно параметр передавать компатор(не знаю как правильно называется). В сети нашел несколько примеров, только там этот "компатор" был классом у которого много разных методов и перегруженных операторов. Тупо copy/paste не стал делать, хотел бы разобраться что и зачем.
Если кто знает, подкажите пожалуйста как сделать так, что бы в этом контейнере сортировка была по неубыванию.
Буду благодарен.
2) умножить все на -1.
Надо специально для таких умножающих на -1 дать задачу, где были бы ограничения
-2147483648 <= value <= 2147483647
Совсем ушлые товарищи могут сделать замену
x -> ~x
.Храним кучу в массиве.
Тогда корень a[1], а сыновья вершины i — 2*i,2*i+1;
Дальше нам нужны две функции — sift_up и sift_down. sift_up проверяет для вершины верно ли, что она больше родителя. Если да — выходим. Иначе меняем местами вершину и ее родителя и рекурсивно запускаемся от родителя. sift_down проверяет, что вершина меньше ее сыновей. Если да — выходим. Иначе меняем вершину с ее МЕНШЬШИМ сыном и запускаемся от него. Реализовывается это довольно просто.
А алгоритм решения задачи таков. Запускаем sift_up по очереди от всех элементов массива слева направо. Затем m раз увеличиваем a[1] и запускаем sift_down(1), чтобы "утопить" вершину и получить новый минимум. Ответ будет в a[1].
Если что непонятно — спрашивайте.
В чем проблема написать бинпоиск по ответу или вообще в тупую за N?
UPD: написал динамику за N. Accepted. http://pastebin.com/XSi9hAfN
Будут вопросы — спрашивай.
Вроде как N log N, сортировка все-таки.
Там в принципе можно подсчетом сортировать
Я вроде как написал, что динамика за N. А сортировка NlogN да.
Можно еще массив в set засунуть и m раз сделать ++(*a.begin());
Немного оффтопа — как уже написали выше, можно решать с мультисетом, и брать минимум как mset.begin(); можно написать бинпоиск по ответу (и при фиксированном ответе проверять, влезет ли нужное количество конфет наивно); а еще можно написать ту же симуляцию, но блочно (т.е. вместо первого элемента рассматриваем весь первый блок из элементов, у которых одинаковое значение — мы можем за одну операцию заполнить этот блок и объединить его со следующим, или же посчитать ответ, если остался единственный блок или конфет не хватит для того, чтобы сравнять текущий первый блок с текущим вторым).
Спасибо всем большое!
Я пробовал через multiset, тоже получаю TL на 10 тесте.
Вот решение, может я что-то не правильно реализовал..?
И еще, не у кого нету реализации min-heap? хотел бы посмотреть на хорошую реализацию.
Я в книге Кормена (Алгоритмы, посмтроение и анализ) прочитал главу, поробовал реализовать — не получилось.
Не понятно, что ты пишешь.
Простое моделирование за MlogN = 10^7 в худшем случае.
for i = 1 .. m (*A.begin())++;
http://code.google.com/p/yaal/source/browse/lib/main/net/egork/collections/heap/Heap.java
(массив at и все, что с ним связано, лучше удалить, если он действительно не нужен)
Правда, непонятно, зачем, когда есть priority_queue. Лучше запомни, как собственный компаратор в нее передавать.
Кажется, тебе очень помогут вот эти видеокурсы. Описание кучи и пирамидальной сортировки там тоже есть.
http://e-maxx.ru/algo/randomized_heap
MinMax Heap в 10 строчек,очень хорошо расписано.