Sunteți pe pagina 1din 2

Problema Turnuri - descrierea soluției.

Norbert Bereczki , Alex Cociorvă, Mircea Popoveniuc - Universitatea Babeș Bolyai

Soluție 1 - O(N*M)

Pentru acesta soluție putem considera punctele ca celule dintr-o matrice, iar ideea de rezolvare este
următoarea: fixam celulele din matrice ce nu aparține vreunui turn astfel încât în acestă celulă să
putem număra toate dreptunghiurile ce au coltul dreapta jos în aceea celula.
Parcurgem pe linii și pe coloane matricea. Ne aflam pe linia i și coloana j, și ne fixam colțul dreapta
jos în i,j. De asemenea în acest punct avem nevoie să știm distanța până la ultimul turn de care am
trecut pe linia i și ce este în stânga coloanei j. Acest lucru se poate ține într-o variabilă
last_tower_dist. Pe măsură ce trecem într-o celulă ce nu aparține unui turn incrementăm cu 1
această valoare, iar când suntem într-o celulă dintr-un turn atunci atribuim acestei variabile valoarea
0.
Astfel în celula i,j calculăm numărul de dreptunghiuri ce au coltul dreapta jos în i,j după formula:
(last_tower_dist-1)*(n-1-i) și îl adăugăm la soluție modulo 109 + 7.
Aceasta soluție poate lua 40 de puncte.

Solutie 2 - O(N*T)

Pornim de sus în jos pe linii cu un set de intervale.


Inițial avem în set numai intervalul [0,M-1].
Fixam o linie și facem următoarele operații:

1. Dacă pe linia aceea se termina un turn (de înălțime h, si care e situat intre coloanele l,r
inclusiv) atunci spargem intervalul din set, ce conține intervalul turnului [l,r] ca
subinterval, în maxim 2 alte intervale. Sa presupunem ca avem un interval in set
[l_int,r_int] și trebuie să spargem acest interval folosind intervalul unui turn,
atunci cele doua intervale noi sunt: [l_int,l-1] si [r+1,r_int].

2. Pentru fiecare interval din set [l,r] calculam toate dreptunghiurile cuprinse intre
coloanele l,r , care au latura de jos a dreptunghiului pe linia curentă și adăugam la
soluție rezultatul. Formula pentru un interval ar fi
(N-1-linia_curenta)*((r-l)(r-l+1)/2)

Având în vedere că sunt 103 turnuri nu vom avea mai mult de 103 intervale în set.
Astfel complexitatea ar fi O(N*T) - N de la fixatul fiecărei linii.
Se mai poate porni de jos în sus cu intervalele de pe lângă și dintre turnuri și când se ajunge la o linie
a unui turn se face merge la unele intervale.
Aceasta soluție poate lua 60 de puncte.

Solutie 3 - O(T log T)

Pornind de la solutia de 60 de puncte, facem urmatoarea observatie. Putem procesa doar liniile in care
se termina un turn. Pentru asta, vom sorta turnurile in ordine descrescatoare dupa inaltimi. Pastram un
set de intervale care initial contine intervalul [0,M-1] si procesam turnurile pe rand. La fiecare turn
procesat, “spargem” intervalul care contine turnul respectiv si numaram cate dreptunghiuri valide sa
adunam la solutie.
De exemplu, daca avem un interval [a,b] pe care il spargem cand intalnim un turn de inaltime h
care se intinde pe [l,r], atunci intervalul se va sparge in [a;l-1] si [r+1;b].

Inainte de a sparge intervalul [a,b], pentru numararea dreptunghiurilor, cand ajungem la turnul mai
mic, trebuie sa numaram dreptunghiurile cu latura de jos intre turnul mic si marginea de la ultima data
cand a fost spart intervalul (adica la procesarea turnului mare) - adica zona B. Pentru asta, din
numarul total de dreptunghiuri intre turnul mic si marginea superioara a foii (reuniunea dintre zonele
A si B), scadem numarul total de dreptunghiuri intre marginea de la ultima data cand a fost spart
intervalul si marginea superioara a foii (zona A). Se face numaratoarea in asa fel pentru a nu se
numara acelasi dreptunghi de mai multe ori.

Numarul total de dreptunghiuri aflate intre zona de inaltime h si latime w este


comb(h,2)*comb(w,2) = h*(h-1)*w*(w-1)/4. Cu aceasta formula se poate calcula usor
cate dreptunghiuri exista cu marginea de jos in regiunea B si marginea de sus in oricare din regiunile
A si B.