Практика по алгоритмам #1 AVL, Treap, Implicit key, Persistent

advertisement
Ïåðâûé êóðñ, âåñåííèé ñåìåñòð
Ïðàêòèêà ïî àëãîðèòìàì
#1
AVL, Treap, Implicit key, Persistent
Contents
1
Íîâûå çàäà÷è
2
2
Ðàçáîð çàäà÷
3
3
Äîìàøíåå çàäàíèå
7
4
3.1
Îáÿçàòåëüíàÿ ÷àñòü
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2
Äîïîëíèòåëüíàÿ ÷àñòü
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
7
Ðàçáîð äîìàøíåãî çàäàíèÿ
8
4.1
Îáÿçàòåëüíàÿ ÷àñòü
8
4.2
Äîïîëíèòåëüíàÿ ÷àñòü
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
8
1
Íîâûå çàäà÷è
1. Êîëè÷åñòâî äåðåâüåâ ïîèñêà èç
n
ðàçëè÷íûõ ýëåìåíòîâ.
2. Çàäà÷è ïðî AVL
root.l.h = root.r.h + 3.
Ïóñòü root.l.h = root.r.h + k.
Ïðèäóìàéòå merge çà O(log n).
2
Ïðèäóìàéòå split çà O(log n).
a) Ïóñòü
Êàê ïåðåáàëàíñèðîâàòü äåðåâî çà
b)
Êàê ïåðåáàëàíñèðîâàòü äåðåâî çà
c)
d)
O(1)?
O(k)?
e) Óìåíüøèòå êîëè÷åñòâî äîïîëíèòåëüíîé èíôîðìàöèè äî äâóõ áèò íà âåðøèíó.
3. Ïðîñòûå çàäà÷è
a) Çàïðîñû:
äîáàâèòü ïàðó
òàêèì, ÷òî
óäàëèòü ïàðó
hx, yi;
ïîñ÷èòàòü ñóììó
y
ïî âñåì ïàðàì
y ïî âñåì ïàðàì òàêèì, ÷òî l ≤ x ≤ r;
ïîñ÷èòàòü ñóììó x ïî âñåì ïàðàì òàêèì, ÷òî l ≤ y ≤ r .
c) Çàïðîñû: äîáàâèòü x; ïîñ÷èòàòü ñóììó x : l ≤ x ≤ r ; ïîñ÷èòàòü ñóììó x, äîáàâëåííûõ â
ìîìåíòû âðåìåíè ñ l ïî r .
d) Ïðåäûäóùàÿ çàäà÷à ïëþñ çàïðîñ óäàëåíèÿ x.
Íàó÷èòüñÿ îáðàáàòûâàòü çàïðîñû: add(i, x), del(i), add(l, r, value), sum(l, r)
b) Çàïðîñû: äîáàâèòü ïàðó
4.
hx, yi;
l ≤ x ≤ r.
hx, yi;
ïîñ÷èòàòü ñóììó
5. Òîæå ñàìîå, íî ïðèáàâëåíèå ïî ìîäóëþ 5, à ñóììà ïî-ïðåæíåìó áåç ìîäóëÿ.
6. Çàäà÷è ïðî Treap
a) Ïðèäóìàéòå ïî àíàëîãèè ñ insert ðåàëèçàöèþ îïåðàöèè delete ÷åðåç 1 merge
b) Íóæíî îáðàáàòûâàòü çàïðîñû
add, del, find.
Ïóñòü ìû ðåøàåì çàäà÷ó äåêàðòîâûì
äåðåâîì (áåç õåø-òàáëèöû). Ïóñòü åñòü äâà òèïà ýëåìåíòîâ ìàëåíüêîå ìíîæåñòâî
c)
è
kA çàïðîñîâ k A, kB çàïðîñîâ ê B . Êàê ñäåëàòü ñóììàðíîå
âðåìÿ ðàáîòû ðàâíûì O(kA log |A| + kB log |B|).
Ìû õîòèì õðàíèòü ïàðû hai , bi i. Ìîæíî ëè ïî êëþ÷ó ai ïîñòðîèòü äåêàðòîâî äåðåâî, à
â êàæäîé âåðøèíå äåðåâà ïîääåðæèâàòü ñóììó âñåõ bi â ïîääåðåâå? Çà ñêîëüêî áóäóò
ðàáîòàòü îïåðàöèè ñ òàêèì äåðåâîì? À ìîæíî ïîääåðæèâàòü äåêàðòîâî äåðåâî âñåõ bi â
áîëüøîå ìíîæåñòâî
B.
A
Ïóñòü
ïîääåðåâå? Çà ñêîëüêî áóäóò ðàáîòàòü îïåðàöèè ñ òàêèì äåðåâîì?
Merge(áàìáóê
Merge(áàìáóê èäóùèé âïðàâî-âíèç, âåðøèíà).
e) Ïðîáëåìà ñ îäèíàêîâûìè êëþ÷àìè. ×òî áóäåò, åñëè Add = GoDown + Split? Çàìåòèì,
÷òî GoDown ìîæíî äåëàòü äâóìÿ ñïîñîáàìè: if(root.x > x) è if(root.x ≥ x).
Ïðåäúÿâèòå n îïåðàöèé ñ persistent RBST (add, delete, split, merge), êîòîðûå ðàáîòàþò çà
Θ(n2 ). Åñòü ëè òàêàÿ ïîñëåäîâàòåëüíîñòü îïåðàöèé äëÿ AVL-äåðåâà (ó êîòîðîãî åñòü òîëüêî
d) Íàðèñóéòå âñå äåðåâüÿ, êîòîðûå ìîãóò ïîëó÷èòüñÿ â ðåçóëüòàòå îïåðàöèè
èäóùèé âëåâî-âíèç, âåðøèíà)
7.
è
add è delete)?
8. Persistent List: çàïðîñû
a) Âñåãî íå áîëåå
N
merge, (push/pop)(front/back).
çàïðîñîâ.
b) À åñëè èçíà÷àëüíî ÷èñëî çàïðîñîâ íå èçâåñòíî?
9. Çàäà÷à âñòàâêà êëþ÷à. Èçíà÷àëüíî âñå ÿ÷åéêè ïóñòû. Íóæíî îáðàáàòûâàòü çàïðîñû âèäà
Insert(i, x). Ïðè ýòîì, åñëè i-ÿ ÿ÷åéêà çàíÿòà, âñå
(5, 1); (5, 2); (5, 3); (1, 7); (1, 8); (2, 9) → 8, 9, 7, 0, 3, 2, 1.
2
ýëåìåíò ñäâèãàþòñÿ âïðàâî. Ïðèìåð:
2
1.
Ðàçáîð çàäà÷
Êîëè÷åñòâî äåðåâüåâ ïîèñêà èç n ðàçëè÷íûõ ýëåìåíòîâ.
Îòâåò 2b.
n-å
÷èñëî Êàòàëàíà.
Çàäà÷è ïðî AVL: âðàùåíèå íà k .
Èíäóêöèÿ:
h è h−k , òî ìû ìîæåì
h èëè h+1. Áàçà. k = 2.
åñëè åñòü äåðåâî ñ äåòüìè âûñîòû
ïîëó÷èòü êîððåêòíîå AVL äåðåâî âûñîòû èëè
çà
O(k)
âðàùåíèé
Ïåðåõîä. Ñäåëàåì
îäíî ìàëîå âðàùåíèå â íóæíóþ ñòîðîíó. Ïîëó÷èì ñ òîé ñòîðîíû äèñáàëàíñ íå áîëåå
èñïðàâèì åãî ïî èíäóêöèè.
2, èñïðàâèì åãî.
T (k) = 1 + T (k − 1) + T (2) = O(k).
Ïîñëå ýòîãî â êîðíå ìîæåò áûòü äèñáàëàíñ
Ïðîâåðèì âûñîòó ïîëó÷åííîãî äåðåâà. Âðåìÿ ðàáîòû
2c.
k−1,
Ïðèäóìàéòå merge çà O(log n).
Ðåøåíèå
#1:
O(log n). Ñäåëàåì åãî
O(log n), èñïîëüçóÿ (2b).
îòùåïèì ó ëåâîãî äåðåâà êðàéíèé ïðàâûé ýëåìåíò çà
êîðíåì, ïîäâåñèì ê íåìó íàøè äâà äåðåâà, ïåðåáàëàíñèðóåì çà
#2:
Merge(l, r) {
if (!l || !r) return l ? l : r;
if (l->h <= r->h)
r->l = Merge(l, r->l), Rebalance(r);
else
l->r = Merge(l->r, r), Rebalance(l);
}
Ðåøåíèå
Ìîæíî äîêàçàòü, ÷òî äàííûé êîä âûäàñò äåðåâî âûñîòû íå áîëåå
ðàáîòû
2d.
max(l->h, r->h)+1.
Âðåìÿ
O(log n).
Ïðèäóìàéòå split çà O(log2 n).
def Split(t, x):
if (t == null):
return (null, null)
if (t.x < x):
(l, r) = Split(t.r, x)
return (Merge(t.l, node(t.x, null, null), l), r)
else:
(l, r) = Split(t.l, x)
return (t.l, Merge(r, node(t.x, null, null), t.r))
Îòäåëåíèå
êîðíåâîãî
êîððåêòíûìè
óçëà
íóæíî
AVL-äåðåâüÿìè.
äëÿ
Âìåñòî
t.r = l; Rebalance(t); O(log n)
O(log n), èòîãîâàÿ ñëîæíîñòü O(log2 n).
äåëàòü
2e.
òîãî,
÷òîáû
âñå
ñëèâàåìûå
äåðåâüÿ
Merge(t.l, node(t.x, null, null), l)
áûëè
ìîæíî
óðîâíåé ðåêóðñèè, íà êàæäîì Merge/Rebalance çà
Óìåíüøèòå êîëè÷åñòâî äîïîëíèòåëüíîé èíôîðìàöèè äî äâóõ áèò íà âåðøèíó.
 êàæäîé âåðøèíå âìåñòî âûñîòû ïîääåðåâà õðàíèì ðàçíèöó âûñîò ëåâîãî è ïðàâîãî
ñûíîâåé,
l.h−r.h,
êîòîðàÿ ìîæåò ïðèíèìàòü çíà÷åíèÿ
{-1, 0, 1}.
Äëÿ òîãî, ÷òîáû óçíàâàòü,
÷òî ðàçíèöà âûñîò ñûíîâåé ïîñëå èõ ðåêóðñèâíîé îáðàáîòêè èçìåíèëàñü (è òàêèì îáðàçîì
óçíàâàòü, åñòü ëè äèñáàëàíñ), ìîæíî èç ðåêóðñèâíûõ ôóíêöèé, ìåíÿþùèõ äåðåâî ê êîðíåì
t, äîïîëíèòåëüíî âîçâðàùàòü, íàñêîëüêî èçìåíèëàñü âûñîòà t (îïÿòü æå {-1, 0, 1}).
íàó÷èòüñÿ ïåðåñ÷èòûâàòü ðàçíîñòè ïðè ïîâîðîòàõ.
âû÷èñëèòü
îòíîñèòåëüíóþ âûñîòó âñåõ óçëîâ,
Äëÿ ýòîãî, íàïðèìåð, ìîæíî ÿâíî
ó÷àñòâóþùèõ â ïîâîðîòå, îòíîñèòåëüíî êîðíÿ
ïîääåðåâà. Ïîñëå ýòîãî íåñëîæíî ïîíÿòü, ïî êàêèì ôîðìóëàì âñå ïåðåñ÷èòàåòñÿ.
3
Îñòàëîñü
3a.
Çàïðîñû: äîáàâèòü hx, yi; óäàëèòü hx, yi; ïîñ÷èòàòü ñóììó y ïî âñåì hx, yi : l ≤ x ≤ r .
Ñì. ëåêöèþ :)
3b.
Çàïðîñû: äîáàâèòü hx, yi; ïîñ÷èòàòü ñóììó y ïî âñåì hx, yi : l ≤ x ≤ r ;
ïîñ÷èòàòü ñóììó x ïî âñåì hx, yi : l ≤ y ≤ r .
Ïîñòðîèòü
3c-d.
äâà
äåðåâà
äîïîëíèòåëüíûì ïîëåì
x.
ïî
êëþ÷ó
x
ñ
äîïîëíèòåëüíûì
ïîëåì
y,
è
ïî
êëþ÷ó
y
ñ
Çàïðîñû: äîáàâèòü x; óäàëèòü x; ïîñ÷èòàòü ñóììó x : l ≤ x ≤ r ;
ïîñ÷èòàòü ñóììó x, äîáàâëåííûõ â ìîìåíòû âðåìåíè ñ l ïî r .
Ìîæíî çàâåñòè äâà äåðåâà, êàê â (3b), èñïîëüçóÿ â êà÷åñòâå
y
âðåìÿ äîáàâëåíèÿ ýëåìåíòà.
 ñëó÷àå áåç óäàëåíèÿ âìåñòî âòîðîãî äåðåâà, êëþ÷îì êîòîðîãî ÿâëÿåòñÿ âðåìÿ äîáàâëåíèÿ,
ìîæíî èñïîëüçîâàòü ïðîñòî ìàññèâ ïðåôèêñíûõ ñóìì â
â ìîìåíòû âðåìåíè ñ
4.
1
ïî
i-é
ÿ÷åéêå ñóììà
x,
äîáàâëåííûõ
i.
Íàó÷èòüñÿ îáðàáàòûâàòü çàïðîñû: add(i, x), del(i), add(l, r, value), sum(l, r)
Ïîñòðîèì äåêàðòîâî äåðåâî ïî íåÿâíîìó êëþ÷ó íà íàøåì ìàññèâå.
count
pending äåðåâà áóäåì õðàíèòü äîïîëíèòåëüíóþ èíôîðìàöèþ:
ïîääåðåâå,
sum
ñóììà çíà÷åíèé â ïîääåðåâå è
ñîáèðàåìñÿ äîáàâèòü â äàííîå ïîääåðåâî.
push
 êàæäîé âåðøèíå
êîëè÷åñòâî ýëåìåíòîâ â
÷èñëî, êîòîðîå ìû ëåíèâî
Êàæäûé ðàç, êîãäà çàõîäèì â âåðøèíó äåëàåì
pending âíèç. Êàæäûé ðàç, êîãäà ìåíÿåì âåðøèíó, äåëàåì update
count è sum. Ìîäèôèöèðóåì split è merge ñëåäóþùèì îáðàçîì:
def split(t, predicate): # íàïðèìåð, predicate "<= x"
if t == null: return (null, null)
push(t)
if predicate(t.key):
(l, r) = split(t.l, predicate)
t.l = r
update(t)
return (l, t)
else:
(l, r) = split(t.r, predicate)
t.r = l
update(t)
return (t, r)
def merge(a, b):
if a == null: return b
if b == null: return a
if a.priority > b.priority:
push(a)
a.r = merge(a.r, b)
update(a)
return a
else:
push(b)
b.l = merge(a, b.l)
update(b)
return b
ïðîòàëêèâàåì
ïåðåñ÷èòûâàåòì
push è update îïðåäåëèì ñëåäóþùèì îáðàçîì:
4
def push(t):
if (t.pending != 0)
if (t.l != null) t.l.pending = t.l.pending + t.pending
if (t.r != null) t.r.pending = t.r.pending + t.pending
t.sum = t.sum + t.count * t.pending
t.pending = 0
def update(t):
t.sum = t.value
t.count = 1
if (t.l != null)
push(t.l)
t.sum = t.sum + t.l.sum
t.count = t.count + t.l.count
if (t.r != null)
push(t.r)
t.sum = t.sum + t.r.sum
t.count = t.count + t.r.count
Òîãäà:
add è del îïðåäåëèì êàê â îáû÷íîì äåêàðòîâîì äåðåâå
b) add(l, r, value) êàê split ïî ≥ l è > r , äîáàâëåíèå value â pending êîðíÿ ñðåäíåãî êóñêà
(åñëè îí íå ïóñò) è merge îáðàòíî
c) sum(l, r) êàê split ïî ≥ l è > r , âçÿòèå sum èç êîðíÿ ñðåäíåãî êóñêà (åñëè îí íå ïóñò) è
merge îáðàòíî
Çàìåòèì, ÷òî push è update ðàáîòàþò çà O(1), ñëåäîâàòåëüíî àñèìïòîòèêà split è merge íå
èçìåíèëàñü. Âñå îïåðàöèè ñîñòîÿò èç O(1) split è merge, ñëåäîâàòåëüíî ðàáîòàþò çà O(log n).
a)
5.
Òîæå ñàìîå, íî ïðèáàâëåíèå ïî ìîäóëþ 5, à ñóììà ïî-ïðåæíåìó áåç ìîäóëÿ.
Âîçüìåì êîíñòðóêöèþ èç ïðåäûäóùåé çàäà÷è, òîëüêî âìåñòî ÷èñëà
count áóäåì õðàíèòü
update òåïåðü áóäåì
ïÿòèýëåìåíòíûé ìàññèâ: êîëè÷åñòâî íóëåé, êîëè÷åñòâî åäèíèö è ò.ä. Â
öèêëè÷åñêè ñäâèãàòü
6.
count
è ïåðåñ÷èòûâàòü
sum
÷åðåç íåãî.
Çàäà÷è ïðî äåêàðòîâû äåðåâüÿ.
6b. Çàâåäåì 2 îòäåëüíûõ äåðåâà äëÿ ìíîæåñòâ
A
è
B,
íà êàæäóþ îïåðàöèþ áóäåì ïðîâåðÿòü,
êàêîìó ìíîæåñòâó ïðèíàäëåæèò ýëåìåíò è îáðàùàòüñÿ ê ñîîòâåòñòâóþùåìó äåðåâó.
6c. Êàê ïîääåðæèâàòü ñóììó íàïèñàíî â çàäà÷å 4. Ïîääåðæèâàòü äåêàðòîâû äåðåâüÿ çíà÷åíèé
ìîæíî àíàëîãè÷íî, îáúåäèíÿÿ äåðåâüÿ èç äåòåé âåðøèíû, îäíàêî ïðîìåæóòêè çíà÷åíèé
äåðåâüåâ äâóõ äåòåé ìîãóò ïåðåñåêàòüñÿ,
Îáúåäèíÿòü
ïðîèçâîëüíûå
äåêàðòîâû
ñëåäîâàòåëüíî merge çà
äåðåâüÿ
ìû
óìååì
òîëüêî
ñëåäîâàòåëüíî îáùåå âðåìÿ îäíîé îïåðàöèè ìîæåò áûòü ïîðÿäêà
O(log n)
çà
íåâîçìîæåí.
ëèíåéíîå
âðåìÿ,
Θ(n).
6d. a) Íîâàÿ âåðøèíà äîëæíà íàõîäèòüñÿ ïðàâåå âñåõ âåðøèí áàìáóêà.
Çàìåòèì, ÷òî òàêèõ
âîçìîæíûõ êîíñòðóêöèé òîëüêî äâå: ëèáî íîâàÿ âåðøèíà ñòàíîâèòñÿ ïðàâûì ïîòîìêîì
êîðíÿ áàìáóêà, ëèáî îíà ñòàíîâèòñÿ êîðíåì äåðåâà, à áàìáóê åå ëåâûì ïîòîìêîì.
A è B òàê, ÷òîáû ó âñåõ âåðøèí â A áûë áîëüøèé ïðèîðèòåò,
÷åì ó íîâîé âåðøèíû, à ó B ìåíüøèé. Òîãäà, íîâàÿ âåðøèíà ñòàíîâèòñÿ ïðàâûì
ïîòîìêîì ëèñòà A è êîðåíü B ñòàíîâèòñÿ ëåâûì ïîòîìêîì íîâîé âåðøèíû.
b) Ðàçðåæåì áàìáóê íà ÷àñòè
5
6e.
Ïðîáëåìà ñ îäèíàêîâûìè êëþ÷àìè.
Ïðåäëàãàåòñÿ ñëåäóþùèé ðàáîòàþùèé âàðèàíò.
def add(t, x, y):
if t.y > y:
if x >= t.key:
t.r = add(t.r, x, y)
else
t.l = add(t.l, x, y)
return t
else:
(l, r) = split(t, predicate(<= x)) # <= x, > x
return node(x, y, l, r)
Çàìåòèì, ÷òî åñëè 'x >= t.key' çàìåíèòü íà 'x > t.key',
êîððåêòíî. Ñóòü â òîì, ÷òî ìû ñ÷èòàåì, ÷òî íîâûé x áîëüøå
çðåíèÿ ïîðÿäêà â äåêàðòîâîì äåðåâå.
êîä
ïåðåñòàíåò
ðàáîòàòü
âñåõ ðàâíûõ åìó ñ òî÷êè
Åñëè ïîðÿäîê íà êëþ÷àõ îïðåäåë¼í îäíîçíà÷íî è
êîððåêòíî, äåêàðòîâî äåðåâî ñóùåñòâóåò è åäèíñòâåííî.
7.
Ïðèìåð, íà êîòîðîì n îïåðàöèé ñ persistent RBST ðàáîòàþò çà Θ(n2 )
n, òî åãî âûñîòà log n, à âñå îïåðàöèè ïðîèñõîäÿò çà Θ(log n).
n
ìåíåå, åñëè âçÿòü t1 = new node(x), ti+1 = Merge(ti , ti ), òî |tn | = 2 , ñîîòâåòñòâåííî,
n, âðåìÿ î÷åðåäíîé îïåðàöèè Θ(n). Ó AVL-äåðåâà ïî óñëîâèþ çàäà÷è íåò îïåðàöèè
Åñëè äåðåâî èìååò ðàçìåð
Òåì íå
âûñîòà
Merge,
8.
ïîýòîìó òàêèõ ïðîáëåì íå ñóùåñòâóåò.
Persistent List ñ îïåðàöèÿìè Push, Pop, Merge
Persistent List íóæíî ðåàëèçîâûâàòü íà Persistent RBST, òàê êàê íàì íóæíî
ïîääåðæèâàòü çàïðîñû Merge. Çà n çàïðîñîâ, êàê ìû óâèäåëè â ïðåäûäóùåé çàäà÷å, ðàçìåð
n
ìîæåò óâåëè÷èòüñÿ äî 2 . (à) Ìû çíàåì, ÷òî çàïðîñîâ íå áîëåå N . Òîãäà õðàíèì ëèøü N
ñàìûõ ëåâûõ è N ñàìûõ ïðàâûõ ýëåìåíòîâ. (á) Ìû çàðàíåå íå çíàåì N . Ïðåäïîëîæèì, N
ðàâíî 1. Êàê òîëüêî ïðèä¼ò N +1-é çàïðîñ, ïåðåñòðîèì âñþ ñòðóêòóðà â ïðåäïîëîæåíèè, ÷òî
çàïðîñîâ áóäåò íå áîëåå ÷åì 2N . Ïåðåñòðàèâàåì â ëîá, íàêàòûâàÿ íà ïóñòîå ñîñòîÿíèå N +1
k
îïåðàöèþ. Âðåìÿ ðàáîòû k îïåðàöèé: T (k) = T ( ) + k log k = O(k log k).
2
Còðóêòóðó
9.
Âñòàâêà êëþ÷åâûõ çíà÷åíèé
Çà
n
îïåðàöèé âñòàâîê â ïîçèöèè
1..m
ìû èñïîëüçóåì íå áîëåå ÷åì
Çàâåä¼ì äåðåâî ïî íåÿâíîìó êëþ÷ó íà ìàññèâå äëèíû
Insert(i, x),
íàéä¼ì áëèæàéøóþ ñïðàâà îò
Ñäåëàåì âñòàâêó
îò
i
x-à
íà
i-þ
i
n+m.
ïóñòóþ êëåòêó.
n+m
ïåðâûõ ÿ÷ååê.
×òîáû îáðàáîòàòü çàïðîñ
Óäàëèì ýòó ïóñòóþ êëåòêó.
ïîçèöèþ â íàøå äåðåâå ïî íåÿâíîìó êëþ÷ó. Êàê íàéòè ñïðàâà
áëèæàéøóþ ïóñòóþ êëåòêó?  êàæäîì ïîääåðåâå õðàíèì êîëè÷åñòâî ïóñòûõ êëåòîê.
Åñëè ó íàñ åñòü
Split,
âîçüì¼ì ñóôôèêñ
[i, n+m]
è áóäåì ñïóñêàòüñÿ îò êîðíÿ âëåâî, åñëè â
ëåâîì ïîääåðåâå åñòü ïóñòûå êëåòêè, èíà÷å âïðàâî. Åñëè îïåðàöèè
êîëè÷åñòâî ïóñòûõ êëåòîê ñëåâà îò
i,
ïóñòü ýòî
îïåðàöèè äåëàþòñÿ ñïóñêîì ïî äåðåâó.
6
k,
íàéä¼ì
Split
k+1-þ
íåò, òî ïîñ÷èòàåì
ïóñòóþ êëåòêó.
Îáå
3
Äîìàøíåå çàäàíèå
3.1
2.
Îáÿçàòåëüíàÿ ÷àñòü
(3) Ãëóáèíû âåðøèí â íåñáàëàíñèðîâàííîì äåðåâå.
 îáû÷íîå íåñáàëàíñèðîâàííîå áèíàðíîå äåðåâî ïîèñêà äîáàâëÿåì ðàçëè÷íûå ýëåìåíòû â
ïîðÿäêå
x1 , x2 , . . . , xn .
Ìû õîòèì ïîääåðæèâàòü äåðåâî â âèäå ìàññèâ îòöîâ âñåõ âåðøèí.
Íóæíî ïîñëå êàæäîãî äîáàâëåíèÿ çà
3.
O(log n)
îáíîâëÿòü ìàññèâ îòöîâ.
(3) Ïëîùàäü ïîêðûâàþùåãî ïðÿìîóãîëüíèêà.
Ïðèäóìàòü
ñòóðêòóðó
äàííûõ,
êîòîðàÿ
ñëåäóþùèìè îïåðàöèÿìè, êàæäàÿ çà
ïîääåðæèâàåò
O(log n),
ãäå
ìíîæåñòâî
òî÷åê
S ⊆ N2
ñî
|S| = n:
x.
x.
a) Äîáàâèòü òî÷êó
b) Óäàëèòü òî÷êó
c) Íàéòè
ìèíèìàëüíóþ
ïëîùàäü
ïðÿìîóãîëüíèêà
êîîðäèíàò, êîòîðûé ïîêðûâàåò âñå òî÷êè èç
ñî
ñòîðîíàìè
ïàðàëëåëüíûìè
îñÿì
S , ÷üè êîîðäèíàòû ïî îñè Ox ëåæàò â îòðåçêå
[l, r].
3.2
1.
Äîïîëíèòåëüíàÿ ÷àñòü
(5) Äâóõìåðíûé treap.
Ïðèäóìàéòå àíàëîã treap äëÿ õðàíåíèÿ òî÷åê íà ïëîñêîñòè ñ îïåðàöèÿìè
splitX, mergeX, splitY, mergeY.
2.
Âñå îïåðàöèè äîëæíû ðàáîòàòü çà
o(n).
(5) Òåñò ïðîòèâ íåäî-AVL-äåðåâà.
L.h ≥ R.h + 2 âñåãäà äåëàåò ðîâíî
R.h ≥ 2L.h + 2), äåëàåò Θ(n2 ) îïåðàöèé
ïîñëå n çàïðîñîâ. Ôîðìàëüíî: èçíà÷àëüíî äåðåâî ïóñòî, íóæíî n ðàç âûçâàòü add(root, xi )
2
äëÿ íåêîòîðîé ïîñëåäîâàòåëüíîñòè xi , ÷òî ñóììàðíîå âðåìÿ ðàáîòû Θ(n ).
void add( node* &t, int x ) {
if (t == node::null)
t = new node(x);
else if (t->x == x)
return;
else if (x < t->x) {
add(t->l, x);
if (t->l->h > t->r->h + 1)
t = rot_left(t);
} else {
add(t->r, x);
if (t->r->h > t->l->h + 1)
t = rot_right(t);
}
t->calc();
}
Ïîñòðîéòå òåñò, íà êîòîðîì íåäî-AVL-äåðåâî, êîòîðîå ïðè
îäíî ìàëîå âðàùåíèå âïðàâî (è ñèììåòðè÷íî ïðè
7
4
Ðàçáîð äîìàøíåãî çàäàíèÿ
4.1
2.
Îáÿçàòåëüíàÿ ÷àñòü
Ãëóáèíû âåðøèí â íåñáàëàíñèðîâàííîì äåðåâå.
Çàìåòèì, ÷òî èç ëþáûõ äâóõ áëèæàéøèõ ïî çíà÷åíèþ ýëåìåíòîâ
ïîääåðåâå äðóãîãî, èáî èíà÷å èõ íàèìåíüøèé îáùèé ïðåäîê
x < z < y.
x < y
îäèí íàõîäèòñÿ â
z áóäåò ìåæäó íèìè ïî çíà÷åíèþ:
Îòñþäà ñëåäóåò, ÷òî íîâàÿ âåðøèíà ñòàíåò ðåáåíêîì ëèáî áëèæàéøåãî ñëåâà, ëèáî
áëèæàéøåãî ñïðàâà, à èç íèõ òîãî, êòî íèæå (ïîçæå äîáàâëåí). Íàõîäèòü òàêèå ýëåìåíòû
ìîæíî çà
3.
O(log n),
õðàíÿ âñå â ñáàëàíñèðîâàííîì äåðåâå ïîèñêà.
Ïëîùàäü ïîêðûâàþùåãî ïðÿìîóãîëüíèêà.
x ïàðû hx, yi. Â êàæäîé âåðøèíå òàêæå õðàíèì ìèíèìàëüíûé è
ìàêñèìàëüíûé x è y â ïîääåðåâå. Êàæäîå èç ýòèõ çíà÷åíèé ïåðåñ÷èòûâàåòñÿ ÷åðåç äåòåé
ïðè êàæäîì èçìåíåíèè äåðåâà. Îòâåò íà çàïðîñ: (max_x − min_x) · (max_y − min_y) íà
Õðàíèì â BST ïî
îòðåçêå. Íàõîäèòü ôóíêöèþ íà îòðåçêå ìû óìååò íàïðèìåð, â äåêàðòîâîì äåðåâå ðåçóëüòàò
ïðîñòî õðàíèòñÿ â êîðíå ðåçóëüòàòà
4.2
1.
Split.
Äîïîëíèòåëüíàÿ ÷àñòü
Äâóõìåðíûé treap.
Ñòðóêòóðà: êîðåíü òî÷êà ñ ìèíèìàëüíûì êëþ÷îì
íà 4 ÷åòâåðòè, 4 ïîääåðåâà (rd, ru, ld, lu).
z.
Îòíîñèòåëüíî íå¼ âñå òî÷êè äåëÿòñÿ
×òîáû íå áûëî ïðîáëåì ñ îäèíàêîâûìè
x
è
y,
x è y , à ïî hx, yi è hy, xi.
SplitX(t, l, r, x) {
if (!t) return NULL;
if (t.x < x)
SplitX(t.ru, t.ru, u, x), SplitX(t.rd, t.rd, d, x);
else
SplitX(t.lu, u, t.lu, x), SplitX(t.ld, d, t.ld, x);
r = MergeY(d, u);
}
MergeX(l, r) {
if (!l) return r;
if (!r) return l;
if (l.z < r.z) {
SplitY(r, rd, ru, l.y);
l.rd = MergeX(l.rd, rd);
l.ru = MergeX(l.ru, ru);
} else {
SplitY(r, rd, ru, l.y);
l.rd = MergeX(l.rd, rd);
l.ru = MergeX(l.ru, ru);
}
r = MergeY(d, u);
}
ñîðòèðóåì íå ïî
Ïî÷åìó ýòî ðàáîòàåò áûñòðî? Ñëîæíî îáúÿñíèòü, èíòóèöèÿ òàêàÿ:
T (n) ≤ 3T ( n2 ) ⇒ T (n) = O(nlog4 3 ) = O(n0.793 ).
2.
Òåñò ïðîòèâ íåäî-AVL-äåðåâà.
Ìû ïðåäïîëàãàåì, ÷òî òàêîãî òåñòà íå ñóùåñòâóåò. Äîêàçûâàòü äàííóþ ãèïîòåçó íå óìååì.
8
Download