Ïåðâûé êóðñ, âåñåííèé ñåìåñòð Ïðàêòèêà ïî àëãîðèòìàì #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