Forum jest zablokowane. Podczas blokady nie można dodawać ani edytować wiadomości.
Ostatnie posty
Ja w muz miałem rekurencyjne drzewo przedziałowe. To ile razy je pisałem można policzyć na palcach jednej ręki (jednak ta liczba zwiększyła się dzień wcześniej w trakcie pisania nawet dwuwymiarowego drzewa rekurencyjnego w PLE, które i tak okazało się blefem :P). Rekurencyjne przedziałówki są wolniejsze, ale niektórych zadań się na iteracyjnych nie da zrobić albo jest to dużo mniej wygodne (takich ala bit aktualności mówiący "wszystko pode mną jest bez sensu"), a to był ten przypadek dla mnie.
Moje drzewko musiało wspierać operacje
1) Dodaj x na przedziale
2) Maksuj z x na przedziale
3) Czytaj w punkcie
A co do kol, to uwaga Marcina wydaje się całkiem trafna.
Moje drzewko musiało wspierać operacje
1) Dodaj x na przedziale
2) Maksuj z x na przedziale
3) Czytaj w punkcie
A co do kol, to uwaga Marcina wydaje się całkiem trafna.
Ja nie miałem, żadnego seta w muz, przeskalowywałem sortem i oprócz tego miałem tylko jedno drzewo przedziałowe. Jestem jednak świadom, że mogłem trochę stałą zbić.
Za to seta użyłem w drużynach i oddałem tym samy 2 punkty :(
A co do limitów czasowych to w cia powinny być według mnie bardziej zróżnicowane w obrębie jednego k, żeby rozróżnić rozwiązania, które to robią trochę za wolno od rozwiązań, które tego wcale nie są w stanie przeliczyć. (Trochę smutne, że moje rozwiązanie które działa niewiele dłużej niż te 3 sekundy dostaje 6 punktów).
I ocenianie w kol, też mi się trochę nie podobało. Powinno być tak że jest zawsze 100 kompów tylko dane rosną. A tak jak teraz to wygląda jakby każdy z testów był prawie max testem i jakby rozwiązanie 4-5 razy za wolne miało dostać 1/10.
Za to seta użyłem w drużynach i oddałem tym samy 2 punkty :(
A co do limitów czasowych to w cia powinny być według mnie bardziej zróżnicowane w obrębie jednego k, żeby rozróżnić rozwiązania, które to robią trochę za wolno od rozwiązań, które tego wcale nie są w stanie przeliczyć. (Trochę smutne, że moje rozwiązanie które działa niewiele dłużej niż te 3 sekundy dostaje 6 punktów).
I ocenianie w kol, też mi się trochę nie podobało. Powinno być tak że jest zawsze 100 kompów tylko dane rosną. A tak jak teraz to wygląda jakby każdy z testów był prawie max testem i jakby rozwiązanie 4-5 razy za wolne miało dostać 1/10.
Pewnie używacie STL-owego set'a - ja go unikałem, bo on wolny, alokuje i zwalnia pamięć przy każdej operacji. Może jakby w nim podmienić allocator na jakiś lepszy to by szybciej działał.
Adrian, nie potrafię zrozumieć Twojego rozwiązania. W każdym razie też mam O(n log^2 n), i liniowa pamięć.
Przechodzę prostokąty rosnąco po y2, i trzymam zbiór poziomych odcinków, ich górnych brzegów. Za każdym razem muszę znaleźć w tym zbiorze jakiś odcinek, który przecina nowy prostokąt. Prostokąt mogę tu potraktować jako nieograniczony z góry, co ułatwia sprawę. Jak znajdę przecięcie, to łączę prostokąty i usuwam odcinek ze zbioru.
Odcinek przecina prostokąt na dwa sposoby:
(a) jego lewy wierzchołek znajduje się wewnątrz prostokąta, albo
(b) przecina on pionową półprostą (lewy brzeg naszego prostokąta)
W tym celu mam dwie struktury danych:
(a) Zbiór lewych końców odcinków. Potrzebuję szukać punktów w prostokącie x1 <= x <= x2, y1 <= y. W tym celu mam strukturę danych Priority Search Tree - drzewo binarne, które trzyma najwyższy punkt w korzeniu, a pozostałe są podzielone pionową prostą przez środek.
(b) Zbiór poziomych odcinków. Potrzebuję szukać odcinka przecinającego pionową półprostą. W tym celu mam dwu-wymiarowe Interval Tree, czyli drzewo binarne, które w korzeniu trzyma zbiór odcinków przecinających prostą przez środek, a w poddrzewach odcinki na lewo i na prawo od tej prostej. Zbiór odcinków w korzeniu trzymamy jako dwa zbiory punktów (lewe i prawe końce), każdy z nich to taki sam Priority Search Tree jak w punkcie (a).
Przechodzę prostokąty rosnąco po y2, i trzymam zbiór poziomych odcinków, ich górnych brzegów. Za każdym razem muszę znaleźć w tym zbiorze jakiś odcinek, który przecina nowy prostokąt. Prostokąt mogę tu potraktować jako nieograniczony z góry, co ułatwia sprawę. Jak znajdę przecięcie, to łączę prostokąty i usuwam odcinek ze zbioru.
Odcinek przecina prostokąt na dwa sposoby:
(a) jego lewy wierzchołek znajduje się wewnątrz prostokąta, albo
(b) przecina on pionową półprostą (lewy brzeg naszego prostokąta)
W tym celu mam dwie struktury danych:
(a) Zbiór lewych końców odcinków. Potrzebuję szukać punktów w prostokącie x1 <= x <= x2, y1 <= y. W tym celu mam strukturę danych Priority Search Tree - drzewo binarne, które trzyma najwyższy punkt w korzeniu, a pozostałe są podzielone pionową prostą przez środek.
(b) Zbiór poziomych odcinków. Potrzebuję szukać odcinka przecinającego pionową półprostą. W tym celu mam dwu-wymiarowe Interval Tree, czyli drzewo binarne, które w korzeniu trzyma zbiór odcinków przecinających prostą przez środek, a w poddrzewach odcinki na lewo i na prawo od tej prostej. Zbiór odcinków w korzeniu trzymamy jako dwa zbiory punktów (lewe i prawe końce), każdy z nich to taki sam Priority Search Tree jak w punkcie (a).
A ja naiwnie doszedłem do wniosku, iż rozwiązania takiego jak Pawła (również na posortowanym ciągu) nie opłaca się pisać i lepiej poddać zadanie niż poświęcić czas na wątpliwy punkt, czy dwa...
Teraz będę sobie to wypominał do następnej edycji potyczek...
Teraz będę sobie to wypominał do następnej edycji potyczek...
On Sun, May 18, 2014 at 10:30:37PM +0200, Wojciech Sidor wrote:
> A ja się zapytam co to jest za magia:
[...]
> Wie ktoś co tu się stało?
1) out of disk space or inodes or hardware error
df tmp;df -l tmp; dmesg -T |tail -20
2) $ wc tmp
wc: tmp: Jest katalogiem
0 0 0 tmp
;)
> A ja się zapytam co to jest za magia:
[...]
> Wie ktoś co tu się stało?
1) out of disk space or inodes or hardware error
df tmp;df -l tmp; dmesg -T |tail -20
2) $ wc tmp
wc: tmp: Jest katalogiem
0 0 0 tmp
;)
Jeju, co za fuszera w testach, skoro rozwiązanie Pawła przeszło xdd. Przecież ubija (tzn. wymusza O(n^2) operacji) je test tworzony wzorem, który wrzuciłem w poprzednim temacie ;/. Swoją drogą też dziwne, że nie było paczkowania, do zadania była masa heur. Niby można wiele patternów pakować do jednego testu, ale wtedy poszczególne ich kawałki będą małe i mogą nie ubić na czasie. I to, że ja dostałem 8/10 pkt z czego 2 WA, to też najlepiej o testach nie świadczy.
W muzeum moim zdaniem wcale nie było wysokiego limitu. Ja miałem 2.63/3.00, a Smu 2.01/3.00, a obaj mieliśmy wzorcową złożoność i ja bym się bardzo zdziwił, jakby nie weszło. Choć w ple rzeczywiście jakieś strasznie wielkie.
W założeniach było napisanie algorytmu takiego jaki opisał Kamil. Ale czasy pokazują, że wyszło mi coś zupełnie innego... będę musiał to przeanalizować.
Z tych ciekawszych rzeczy, też miałem problemy z pamięcią. Moje rozwiązanie przekraczało 250MB dla największych testów. O dziwo okazało się, iż winowajcą była kolejka std::queue, która zjada niewyobrażalne ilości pamięci. Naklepanie najbardziej prymitywnej kolejki na vectorze, zmniejszyło zapotrzebowanie do 50MB... i pozwoliło cieszyć się jednym TLE na grupę. :/
Wynika z tego, że nie opłaca się używać STLowej kolejki jak ma się problemy z pamięcią.
Z tych ciekawszych rzeczy, też miałem problemy z pamięcią. Moje rozwiązanie przekraczało 250MB dla największych testów. O dziwo okazało się, iż winowajcą była kolejka std::queue, która zjada niewyobrażalne ilości pamięci. Naklepanie najbardziej prymitywnej kolejki na vectorze, zmniejszyło zapotrzebowanie do 50MB... i pozwoliło cieszyć się jednym TLE na grupę. :/
Wynika z tego, że nie opłaca się używać STLowej kolejki jak ma się problemy z pamięcią.
Mój program przechodził po kolejnych początkowych wierzchołkach prostokątów (jakaś lista/kolejka). Na początku była ona wypełniona posortowanymi niemalejąco punktami x1, sprawdzał czy są takie obszary, których x1 jest co najwyżej taki jak jego, a x2 jest większy od x1 aktualnie analizowanego. Wartość x1 tego złączonego obszaru dodawał na początek tej listy. I zaczynał od nowa dla aktualnie pierwszego elementu tej listy/kolejki.
Samo wyszukiwanie obszarów, o x2 większym od x1 obecnego i zarazem x1 nie większym, przeprowadzałem na drzewie przedziałowym.
W skrócie tak. Złożoność O(n*log^2(n)). Dostałem 10/10.
Samo wyszukiwanie obszarów, o x2 większym od x1 obecnego i zarazem x1 nie większym, przeprowadzałem na drzewie przedziałowym.
W skrócie tak. Złożoność O(n*log^2(n)). Dostałem 10/10.
Nie dziwię się że optymalizowałeś, po tylu maksach z rzędu presja aby nie uronić ani punkta na TLE musi być zabójcza ;)
n^{3/2}log n weszło na 10pkt. nawet nie zbliżając się do limitów czasowych. Trzymałem mapy dla każdej współrzędnej y oraz dla bloków [k*1000, (k+1)*1000) - w ten sposób zapytanie o rogi znajdujące się w danym prostokącie robiłem w sqrt(n)logn. Raz znaleziony róg usuwałem z mapy, żeby się ładnie amortyzowało. Problemem były takie przecięcia obszarów, że róg żadnego nie zawierał się w drugim, ale to można było załatwić na początku jednym przejściem miotłą.
moje rozwiązanie O(n^2):
-posortuj prostokąty po rzutach na oś X,
-w liście trzymamy nieprzecinające się prostokąty,
-dla każdego prostokąta, tak długo jak na liście jest prostokąt, z którym można się połączyć, łączymy, usuwamy stary z listy
dostało 10/10, bez sortowania na początku 3/10
-posortuj prostokąty po rzutach na oś X,
-w liście trzymamy nieprzecinające się prostokąty,
-dla każdego prostokąta, tak długo jak na liście jest prostokąt, z którym można się połączyć, łączymy, usuwamy stary z listy
dostało 10/10, bez sortowania na początku 3/10
Mam tak jak Piotr i Grzegorz. Wyznaczanie LCA zmodyfikowanym algorytmem Tarjana. Max czas 1.31s
Zwykle w Potyczkach bywają strasznie małe limity czasu, a w tej rundzie były olbrzymie, w porównaniu! A ja tak optymalizowałem mój kod :)
Moje najgorsze czasy:
cia 0.07s/3.00s
muz 0.41s/3.00s
ple 0.33s/16.00s
fio 0.64s/6.00s
Moje najgorsze czasy:
cia 0.07s/3.00s
muz 0.41s/3.00s
ple 0.33s/16.00s
fio 0.64s/6.00s