[Algorytmy] Drzewo przedziałowe typu przedział-przedział

zhtk
Użytkownik
Użytkownik
Posty: 13
Rejestracja: 2 kwie 2012, o 10:53
Płeć: Mężczyzna
Lokalizacja: Warszawa
Pomógł: 2 razy

[Algorytmy] Drzewo przedziałowe typu przedział-przedział

Post autor: zhtk »

Witam, jestem początkującym adeptem informatyki, mam tutaj kod napisany przez Pana M. M. Sysło:

Kod: Zaznacz cały

void insert(int a, int b, int v)
{
          int l = N + a, r = N + b;
          int length = 1; // długość przedziałów na aktualnie odwiedzanym poziomie
          load[l] += v;
          sub[l] += v;
          // jeśli a==b to nie dodajemy obciążenia dwukrotnie
          if(r != l)
          {
                    load[r] += v;
                    sub[r] += v;
          }
          while(l >= 1)
          {
                    // jeśli l i r nie są sąsiadami w drzewie, to sprawdzamy czy
                    // nie trzeba uaktualnić węzłów wewnętrznych
                    if(l < r - 1)
                    {
                              if(l % 2 == 0) // l jest lewym synem swego ojca
                              {
                                        load[l + 1] += v;
                                        sub[l + 1] += v * length;
                              }
                              if(r % 2 == 1) // r jest prawym synem swego ojca
                              {
                                        load[r - 1] += v;
                                        sub[r - 1] += v * length;
                              }
                    }
                    // jeśli l i r nie są liśćmi, to uaktualniamy ich wartości sub
                    if(r < N)
                    {
                              sub[l] = sub[2 * l] + sub[2 * l + 1] + load[l] * length;
                              sub[r] = sub[2 * r] + sub[2 * r + 1] + load[r] * length;
                    }
                    // przechodzimy poziom wyżej
                    l /= 2; r /= 2; length *= 2;
          }
}

int query(int a, int b)
{
          int l = N + a, r = N + b;
          int length = 1; // długość przedziałów na aktualnie odwiedzanym poziomie
          // w llen i rlen pamiętamy ile punktów przedziału [a,b] zawiera
          // się w poddrzewie o korzeniu l i r odpowiednio
          int llen = 1, rlen = (a != b ? 1 : 0);
          int res = 0;
          while(l >= 1)
          {
                    // sumujemy obciążenia z węzłów l i r
                    res += llen * load[l] + rlen * load[r];
                    // jeśli l i r nie są sąsiadami w drzewie to sprawdzamy czy
                    // istnieją węzły wewnętrzne z obciążeniem
                    if(l < r - 1)
                    {
                              if(l % 2 == 0) // l jest lewym synem swego ojca
                              {
                                        res += sub[l + 1];
                                        llen += length;
                              }
                              if(r % 2 == 1) // r jest prawym synem swego ojca
                              {
                                        res += sub[r - 1];
                                        rlen += length;
                              }
                    }
                    // przechodzimy poziom wyżej
                    l /= 2; r /= 2; length *= 2;
          }
          return res;
}
Pozwoliłem sobie pominąć nagłówki i funkcję main, a także deklaracje (definicje?) tablic. Zasadniczo to moje pytanie brzmi: jaka jest naczelna idea działania tego algorytmu? Komentarze niewiele mi tu wyjaśniają. Gdyby ktoś z Państwa zaprezentował mi dowód poprawności to byłbym bardzo wdzięczny. Niestety WAS nie za bardzo mi pomaga, gdyż jestem początkujący i wykład przerasta moje możliwości poznawcze i intelektualne. Z góry dziękuję za udzieloną pomoc.
Ostatnio zmieniony 4 kwie 2012, o 22:08 przez Afish, łącznie zmieniany 2 razy.
Powód: Poprawa wiadomości.
Kartezjusz
Użytkownik
Użytkownik
Posty: 7330
Rejestracja: 14 lut 2008, o 08:31
Płeć: Mężczyzna
Lokalizacja: Z Bielskia-Białej
Podziękował: 6 razy
Pomógł: 961 razy

[Algorytmy] Drzewo przedziałowe typu przedział-przedział

Post autor: Kartezjusz »

Powiedz co ma być programowane ? Na pewno nie dostaliście kodu i macie odgadnąć do programuje...
abc666

[Algorytmy] Drzewo przedziałowe typu przedział-przedział

Post autor: abc666 »

Powiedz co ma być programowane ? Na pewno nie dostaliście kodu i macie odgadnąć do programuje...
Drzewo przedziałowe typu przedział-przedział
?
zhtk
Użytkownik
Użytkownik
Posty: 13
Rejestracja: 2 kwie 2012, o 10:53
Płeć: Mężczyzna
Lokalizacja: Warszawa
Pomógł: 2 razy

[Algorytmy] Drzewo przedziałowe typu przedział-przedział

Post autor: zhtk »

Mam na myśli to:
Chodzi mi o drzewo na którym operację insert można wykonywać nie na punkcie (bo to już znam) ale na przedziale. Kod który zamieściłem jest przykładową implementacją tegoż drzewa. Mój problem polega na tym że muszę umieć coś takiego sam napisać (najlepiej w wersji nierekurencyjnej), a nie za bardzo rozumiem o co w tym kodzie chodzi. Wiem tylko, że w tablicy load i sub są przechowywane dwa drzewa (struktura przypomina trochę kopiec), i że z liści algorytm idzie w górę drzewa. Wykład, który zacytowałem, jest w tej chwili zbyt trudny dla mnie (jestem dopiero początkujący).
ODPOWIEDZ