CZYM JEST DRZEWOCZYMJEST DRZEWO
Drzewo to obiekt w teorii grafów, który nie maDrzewo to obiekt w teorii grafów, który nie ma
cykli i jest spójny, tzn:cykli i jest spójny, tzn:
wychodząc z wierzchołka A nie da się do niego powrócić (przywychodząc z wierzchołka A nie da się do niego powrócić (przy
czym jeśli w pierwszym kroku wykonujemy ruch Aczym jeśli w pierwszym kroku wykonujemy ruch A → B, to w→ B, to w
drugim nie możemy wykonaćdrugim nie możemy wykonać BB → A,→ A, A i B są dowolnymiA i B są dowolnymi
wierzchołkami grafuwierzchołkami grafu))
z dowolnego wierzchołka A można w skończonej ilości krokówz dowolnego wierzchołka A można w skończonej ilości kroków
przejść do dowolnego wierzchołka Bprzejść do dowolnego wierzchołka B
3.
Widzimy, że graften jestWidzimy, że graf ten jest
spójny, ale posiada cyklspójny, ale posiada cykl
(1(1→2→5→1), zatem nie jest→2→5→1), zatem nie jest
drzewemdrzewem
Z kolei ten graf jest zarównoZ kolei ten graf jest zarówno
spójny i acykliczny, zatem jestspójny i acykliczny, zatem jest
drzewemdrzewem
4.
TERMINOLOGIATERMINOLOGIA
Dla dowolnejścieżki prostej rozpoczynającej się
od korzenia i zawierającej wierzchołek V:
wierzchołki występujące w ścieżce przed V nazywamy przodkami
V, a wierzchołki występujące po - potomkami V
wierzchołek poprzedzający V nazywamy rodzicem lub ojcem, a
będący bezpośrednio po - dzieckiem lub synem.
wierzchołki mające wspólnego ojca nazywamy braćmi
Wierzchołki, które nie mają synów nazywamy liśćmi .
Najdłuższą ścieżkę w drzewie
nazywamy średnicą drzewa.
Drzewo z wyróżnionym wierzchołkiem,
korzeniem, nazywamy drzewem ukorzenionym.
5.
DRZEWO W INFORMATYCEDRZEWOW INFORMATYCE
W informatyce jest to struktura danych, któraW informatyce jest to struktura danych, która
reprezentuje drzewo jako obiekt teorii grafów.reprezentuje drzewo jako obiekt teorii grafów.
Umożliwia szybkie wykonanie algorytmów:Umożliwia szybkie wykonanie algorytmów:
Sprawdzenie wartości elementu [w czasie O(log n)]Sprawdzenie wartości elementu [w czasie O(log n)]
Zmianę wartości elementu [w czasie O(log n)]Zmianę wartości elementu [w czasie O(log n)]
Znalezienie maksimum i minimum w przedziale [w czasie O(logZnalezienie maksimum i minimum w przedziale [w czasie O(log
n)]n)]
Zwiększenie wszystkich elementów w przedziale o pewnąZwiększenie wszystkich elementów w przedziale o pewną
wartość [w czasie O(log n)]wartość [w czasie O(log n)]
6.
DRZEWA BINARNEDRZEWA BINARNE
Jest to struktura danych będąca drzewem, którejJest to struktura danych będąca drzewem, której
wierzchołki mają co najwyżej 2 stopień.wierzchołki mają co najwyżej 2 stopień.
Interesujące dla nas są jednak jego pochodneInteresujące dla nas są jednak jego pochodne
7.
Drzewo binarneposzukiwańDrzewo binarne poszukiwań jestjest
dynamiczną strukturą danych zbudowanądynamiczną strukturą danych zbudowaną
zz węzłówwęzłów . Każdy węzeł może posiadać. Każdy węzeł może posiadać
dwóch potomków (dwóch potomków (lewylewy ii prawyprawy) oraz) oraz
jednegojednego przodkaprzodka. Z każdym węzłem. Z każdym węzłem
dodatkowo związany jestdodatkowo związany jest kluczklucz..
Binarne drzewa wyszukiwań częstoBinarne drzewa wyszukiwań często
stosuje się w zadaniach, w którychstosuje się w zadaniach, w których
wymagane jest względnie szybkiewymagane jest względnie szybkie
sortowanie lub wyszukiwanie elementów.sortowanie lub wyszukiwanie elementów.
Drzewo przedziałoweDrzewoprzedziałowe, struktura danych, struktura danych
przechowująca punkty, oraz związane z tymiprzechowująca punkty, oraz związane z tymi
punktami wszystkie możliwe przedziały. Drzewopunktami wszystkie możliwe przedziały. Drzewo
przedziałowe, jeśli jest skonstruowane tak, abyprzedziałowe, jeśli jest skonstruowane tak, aby
było zrównoważone, pozwala odpowiadać nabyło zrównoważone, pozwala odpowiadać na
zapytania o dowolny przedział w czasiezapytania o dowolny przedział w czasie
logarytmicznym.logarytmicznym.
10.
#include <iostream>#include <iostream>
usingnamespace std;using namespace std;
const int MAXN = 1048576;const int MAXN = 1048576;
int n, a[MAXN], intervalTree[2*MAXN];int n, a[MAXN], intervalTree[2*MAXN];
void read() {void read() {
cin >> n;cin >> n;
for(int i=0;i<n;i++) cin >> a[i];for(int i=0;i<n;i++) cin >> a[i];
}}
void buildTree(int node) {void buildTree(int node) {
if(node >= MAXN) { //sprawdzam czy node jest liściemif(node >= MAXN) { //sprawdzam czy node jest liściem
intervalTree[node] = a[node-MAXN];intervalTree[node] = a[node-MAXN];
return; //zawracam, żeby nie wyjść poza zakres danychreturn; //zawracam, żeby nie wyjść poza zakres danych
}}
buildTree(node*2);buildTree(node*2);
buildTree(node*2+1);buildTree(node*2+1);
intervalTree[node] = intervalTree[node*2]+intervalTree[node*2+1]; //obliczamintervalTree[node] = intervalTree[node*2]+intervalTree[node*2+1]; //obliczam
wartość w wierzchołku na podstawie synówwartość w wierzchołku na podstawie synów
}}
int query(int f, int s) { //query już jest iteracyjnyint query(int f, int s) { //query już jest iteracyjny
f = f+MAXN; s = s+MAXN;f = f+MAXN; s = s+MAXN;
if(f == s) return intervalTree[s];if(f == s) return intervalTree[s];
int res = intervalTree[f]+intervalTree[s];int res = intervalTree[f]+intervalTree[s];
while(f/2 != s/2) {while(f/2 != s/2) {
if(f%2 == 0) res = res+intervalTree[f+1];if(f%2 == 0) res = res+intervalTree[f+1];
if(s%2 == 1) res = res+intervalTree[s-1];if(s%2 == 1) res = res+intervalTree[s-1];
f = f/2; s = s/2;f = f/2; s = s/2;
}}
return res;return res;
void update(int f, int s) { //podstawiam a[f] := svoid update(int f, int s) { //podstawiam a[f] := s
int restore = a[f-1];int restore = a[f-1];
a[f-1] = s;a[f-1] = s;
f += MAXN-1;f += MAXN-1;
while(f != 0) {while(f != 0) {
intervalTree[f] += s-restore;intervalTree[f] += s-restore;
f = f/2;f = f/2;
}}
}}
int main() {int main() {
read();read();
buildTree(1); //zaczynamy od korzenia i budujemybuildTree(1); //zaczynamy od korzenia i budujemy
rekurencyjnierekurencyjnie
while(1) {while(1) {
char operationType; int f, s; //typ operacji: Q -char operationType; int f, s; //typ operacji: Q -
zapytanie o sumę (f,s), U - zamienia a[f] na s, E - exitzapytanie o sumę (f,s), U - zamienia a[f] na s, E - exit
cin >> operationType >> f >> s;cin >> operationType >> f >> s;
if(operationType == 'Q') cout << query(f-1,s-1) <<if(operationType == 'Q') cout << query(f-1,s-1) <<
endl; //indeksuje od 0endl; //indeksuje od 0
if(operationType == 'U') update(f,s);if(operationType == 'U') update(f,s);
if(operationType == 'E') return 0;if(operationType == 'E') return 0;
}}
return 0;return 0;
}}