Atenţie! Aceasta este o versiune veche a paginii, scrisă la 2008-12-18 15:11:18.
Revizia anterioară   Revizia următoare  

 

Fişierul intrare/ieşire:heapuri.in, heapuri.outSursăArhiva educationala
AutorArhiva EducationalaAdăugată dedevilkindSavin Tiberiu devilkind
Timp execuţie pe test0.125 secLimită de memorie20480 kbytes
Scorul tăuN/ADificultateN/A

Vezi solutiile trimise | Statistici

Heapuri

Se da o multime de numere cu N elemente. Se cere sa se efectueze M operatii asupra acestei multimi astfel. Operatiile sunt de 3 tipuri:

  • Operatia de tipul 1: inserareaza elementul x in multime
  • Operatia de tipul 2: stergerea elementului x din multime
  • Operatia de tipul 3: care este elementul minim din multime

Daca se incearca inserarea unui element care este deja in multime atunci aceasta operatie se ignora. De asemenea stergerea unui element care nu exista in multime se ignora.

Date de intrare

Fisierul de intrare heapuri.in va contine pe prima linie numarele N si M. Pe a doua linie se vor afla N numere, reprezentand multimea initiala. Pe liniile 3 .. M+2 se vor afla operatiile descrise astfel: un numar cod reprezentand tipul operatiei, iar in caz ca acesta este 1 sau 2 se mai da si un numar x avand semnificatia din enunt.

Date de ieşire

Fisierul de iesire heapuri.out va contine pe cate o linie raspunsul pentru fiecare operatie de tipul 3 din fisierul de intrare.

Restricţii

  • 1 ≤ N ≤ 100 000
  • 1 ≤ M ≤ 100 000
  • Elementele multimii nu vor depasi 1 000 000

Exemplu

heapuri.inheapuri.out
5 6
4 9 7 12
3
1 2
2 4
3
2 2
3
4
2
7

Explicaţie

La prima operatie de tipul 3 multimea arata astfel: {4, 9, 7, 12}
La a doua operatie de tipul 3 multimea arata astfel: {2, 9, 7 12}
la a treia operatie de tipul 3 multimea arata astfel: {9, 7, 12}

Trebuie sa te autentifici pentru a trimite solutii. Click aici

Cum se trimit solutii?

Indicatii de rezolvare

Problema se poate rezolva brut-force tinand numerele intrun vector, si efectuand pur si simplu fiecare operatie. Aceasta solutie are complexitate O(1) pe o operatie de tipul 1 si O(N) pe celelalte si nu ar trebui sa ia ~30 de puncte.

Rezolvarea optima se face folosind un heap, care suporta aceste efectuarea operatiilor de tipul 1 si 2 in O(log N) si a operatiilor de tipul 3 in O(1).
Un heap este un arbore binar echilibrat, cu proprietatea ca fiecare nod, are asociata o cheie, cheie care este mica decat cheile asociate nodurilor din subarborele sau. Evident raspunsul la operatiile de tip 3 se vor gasi in radacina arborelui.
O implementare usoara este aceea de a reprezenta heapul ca pe un vector. Astfel radacina se va afla pe pozitia 1 iar pentru un nod i, fii lui se vor afla pe pozitiile 2*i respectiv 2*i+1.
Cand vrem sa inseram un element nou in vector, il adaugam la capatul sirului, si apoi il interschimbam cu parintele sau pana cand se respecta proprietatea de heap.
De asemenea pentru fiecare element vom tine minte pozitia pe care se afla acesta in vector. Astfel ca atunci cand o sa vrem sa stergem un element din heap, il interschibam cu ultimul element din vector si scadem dimensiunea acestuia cu 1. Totusi acest lucru ne poate strica proprietatea de heap. Astfel avem 2 cazuri:
*Elementul nostru este mai mic decat parintele sau, caz in care aplicam acelasi algoritm pe care il aplicam si atunci cand vrem sa adaugam un nod in heap, adica il interschibam cu parintele sau pana cand se respecta proprietatea de heap.
*Elementul nostru este mai mare decat fii sai, caz in care vom continua sa il interschimbam cu cel mai mic fiu al sau pana cand se va respecta proprietatea de heap.

Puteti citi aici mai multe detalii.

Probleme suplimentare

Paul:
1. Fii atent la brutul in N^2 care cauta minimul doar atunci cand stergi elementul minim si restul cazurilor le trateaza O(1).
2. Nu uita ca se poate face si in sqrt (tii pentru fiecare bucata de sqrt(N+M) minimul) si adaugi bucati pe parcurs.
3. Explica ca lumea cum se face un heap.
4. Baga probleme suplimentare / aplicatii. Explica in ce alte situatii e bun un heap (ex. Dijkstra, Prim).
Cosmin:
De ce e multime si nu colectie de elemente. Nu imi place ca adaugi o restrictie care nu e necesara la heapuri prin faptul ca zici ca elementele apartin unei multimi.
devil
@cosmin: Cand am zis multime ma gandeam mai mult la faptul ca intr-o multime nu poate exista acelasi element de 2 ori, si astfel atunci cand sterg un element e clar ce se intampla. Am uitat insa acest lucru pe parcurs si am uitat sa precizez ca daca un element e deja in heap nu mai intra inca o data si de asemenea am uitat sa pun elementele mai mici ca 100000 ca sa se poate verifica usor acest lucru.
@paul
1. o sa bag un test cu 40000 de inserturi si 40000 de operatii de stergere a minimului si restul queryuri.
2. O sa bag o sursa si sa vad cum fac un test mare.
3. Ma gandeam sa las articolu ala, dar ok explic
4. Caut acuma