Drzewo przedziałowe¶
Opis problemu¶
Implementacja¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
|
Opis implementacji¶
Klasa SumSegmentTree definiuje drzewo przedziałowe do liczenia sum na przedziałach. Struktura node opisuje strukturę wewnętrznego węzła drzewa segmentowego. Węzeł przechowuje informacje o wartości, przedziale, leniwej aktualizacji (lazy update) oraz wskaźniki na lewe i prawe poddrzewo. Węzeł posiada metody do drukowania informacji o sobie, leniwej aktualizacji, zmiany wartości na danym przedziale oraz pobrania sumy wartości na danym przedziale.
Klasa SumSegmentTree posiada pole root, które jest wskaźnikiem na korzeń drzewa segmentowego. Metoda build rekurencyjnie tworzy drzewo segmentowe na podstawie tablicy tab. Konstruktor klasy SumSegmentTree tworzy drzewo segmentowe na podstawie podanej długości i tablicy. Metoda print wywołuje metodę print na korzeniu drzewa segmentowego, co powoduje wypisanie informacji o strukturze drzewa. Metoda change wykonuje operację zmiany wartości na danym przedziale, korzystając z leniwych aktualizacji, natomiast metoda getValue zwraca sumę wartości na danym przedziale.
W funkcji main tworzona jest instancja klasy SumSegmentTree na podstawie przykładowej tablicy. Następnie wywoływana jest metoda print dla wyświetlenia struktury drzewa przed wykonaniem operacji. Wywoływana jest operacja getValue na przedziale \([3, 5]\) i wynik zostaje wyświetlony. Następnie wywoływana jest operacja change na przedziale \([3, 5]\) z wartością \(2\) po czym wyświetlena jest zaktualizowana struktura drzewa. Na końcu obliczana jest aktualna suma na przedziale \([3, 5]\).
Wynik działania programu:
[0, 9]: (val: 10, lazy: 0)
[0, 4]: (val: 5, lazy: 0)
[0, 2]: (val: 3, lazy: 0)
[0, 1]: (val: 2, lazy: 0)
[0, 0]: (val: 1, lazy: 0)
[1, 1]: (val: 1, lazy: 0)
[2, 2]: (val: 1, lazy: 0)
[3, 4]: (val: 2, lazy: 0)
[3, 3]: (val: 1, lazy: 0)
[4, 4]: (val: 1, lazy: 0)
[5, 9]: (val: 5, lazy: 0)
[5, 7]: (val: 3, lazy: 0)
[5, 6]: (val: 2, lazy: 0)
[5, 5]: (val: 1, lazy: 0)
[6, 6]: (val: 1, lazy: 0)
[7, 7]: (val: 1, lazy: 0)
[8, 9]: (val: 2, lazy: 0)
[8, 8]: (val: 1, lazy: 0)
[9, 9]: (val: 1, lazy: 0)
[3, 5] = 3
[3, 5] + 2
[0, 9]: (val: 16, lazy: 0)
[0, 4]: (val: 9, lazy: 0)
[0, 2]: (val: 3, lazy: 0)
[0, 1]: (val: 2, lazy: 0)
[0, 0]: (val: 1, lazy: 0)
[1, 1]: (val: 1, lazy: 0)
[2, 2]: (val: 1, lazy: 0)
[3, 4]: (val: 2, lazy: 2)
[3, 3]: (val: 1, lazy: 0)
[4, 4]: (val: 1, lazy: 0)
[5, 9]: (val: 7, lazy: 0)
[5, 7]: (val: 5, lazy: 0)
[5, 6]: (val: 4, lazy: 0)
[5, 5]: (val: 1, lazy: 2)
[6, 6]: (val: 1, lazy: 0)
[7, 7]: (val: 1, lazy: 0)
[8, 9]: (val: 2, lazy: 0)
[8, 8]: (val: 1, lazy: 0)
[9, 9]: (val: 1, lazy: 0)
[3, 5] = 9