Estructuras de Datos - Fidel
-
Upload
ruben-holguino-borda -
Category
Documents
-
view
228 -
download
0
description
Transcript of Estructuras de Datos - Fidel
Estructuras de datos
Training Camp Argentina 2013
Fidel I. Schaposnik (UNLP) - [email protected] de julio de 2013
Contenidos
Introduccion
set de C++
Mınimo en intervalos (RMQ)
caso estatico: sparse tablescaso dinamico: segment tree
Suma en intervalos
caso estatico: sumas parciales uni- y bi-dimensionalescaso dinamico: binary indexed tree
Operaciones mas generales en intervalos
caso estaticocaso dinamico: square root trick
Problema adicional: ancestro comun mas bajo (LCA)
Training Camp Argentina 2013 Estructuras de datos
Introduccion
¿Que es una estructura de datos?
Una forma de almacenar datos y operar con ellos de modo depoder calcular eficientemente diversas magnitudes.
Puede pensarse como una “caja negra” donde estan los datos(posiblemente sujetos a modificaciones), que nos responderacierto tipo de preguntas de modo eficiente.
¿Como se usa una estructura de datos en una competenciade programacion?
Las etapas o pasos intermedios del algoritmo muchas veces puedenverse como subproblemas menores, que debemos resolver parahallar la respuesta final. Si bien los problemas completos rara vezse repiten, los subproblemas muchas veces son “clasicos”, yconocemos para ellos una estructura de datos adecuada.
Training Camp Argentina 2013 Estructuras de datos
set de C++
El set de C++ representa un conjunto de elementos, quepodemos pensar como ordenados de “menor” a “mayor”. Nospermite realizar distintas operaciones en O(log N):
insertar y borrar elementos (insert y erase, resp.);
fijarnos si un elemento esta presente (find);
encontrar el primer elemento “mayor” o “mayor o igual” queotro (upper bound y lower bound, respectivamente).
Algunas observaciones:
en un conjunto no puede haber repeticiones;
no controlamos el funcionamiento interno de la estructura,solo la funcion de comparacion;
no podemos modificar elementos (pero sı eliminar una versionvieja de un elemento y reemplazarla por una nueva).
Training Camp Argentina 2013 Estructuras de datos
Ejemplo del uso de set de C++
1 #i n c l u d e <i o s t r eam>2 #i n c l u d e <se t>3 u s i n g namespace s t d ;45 i n t main ( ) {6 se t<i n t> c ;78 f o r ( i n t i =−15; i <17; i +=3) c . i n s e r t ( i ) ;9
10 cout << c . s i z e ( ) << end l ;11 f o r ( se t<i n t > : : i t e r a t o r i t=c . beg in ( ) ; i t !=c . end ( ) ; i t++)12 cout << ∗ i t << ’ ’ ;1314 cout << end l << ( c . f i n d (−9)!=c . end ( ) ) << end l ;15 c . e r a s e (−9) ;16 cout << ( c . f i n d (−9)!=c . end ( ) ) << end l ;1718 cout<<∗c . l ower bound (6 )<< ’ ’<<∗c . upper bound (6 )<<end l ;19 cout<<∗c . l ower bound (7 )<< ’ ’<<∗c . upper bound (7 )<<end l ;2021 r e t u r n 0 ;22 }
Ejemplo del uso de set de C++
Training Camp Argentina 2013 Estructuras de datos
Ejemplo del uso de set de C++ (cont.)
Podemos utilizar nuestros propios elementos definiendo un orden
1 s t r u c t pt {2 i n t x , y ;3 pt ( i n t xx=0, i n t yy=0) {4 x=xx ; y=yy ;5 } ;6 } ;78 boo l operator <(const pt &p1 , const pt &p2 ) {9 double a1=atan2 ( p1 . y , p1 . x ) , a2=atan2 ( p2 . y , p2 . x ) ;
10 i f ( a1 != a2 ) r e t u r n a1 < a2 ;11 e l s e r e t u r n p1 . x∗p1 . x+p1 . y∗p1 . y < p2 . x∗p2 . x+p2 . y∗p2 . y ;12 }1314 [ . . . ]1516 se t<pt> p ;1718 p . i n s e r t ( pt ( 1 , 1 ) ) ; p . i n s e r t ( pt ( 2 , 2 ) ) ;19 p . i n s e r t ( pt ( 2 , 1 ) ) ; p . i n s e r t ( pt ( 3 , 5 ) ) ;
Uso del set de C++ con una estructura propia
Training Camp Argentina 2013 Estructuras de datos
Aplicacion: Dijkstra
1 se t< pa i r<i n t , i n t> > s ;23 v o i d d i j k s t r a ( i n t s t a r t , i n t dest , i n t N) {4 f o r ( i n t i =0; i<N; i++) n [ i ] . d = INF ;5 n [ s t a r t ] . d = 0 ; s . i n s e r t ( make pa i r (0 , s t a r t ) ) ;6 w h i l e ( ! s . empty ( ) ) {7 i n t cu r = s . beg in ( )−>second ;8 i f ( cu r == de s t ) break ;9 f o r ( i n t i =0; i <( i n t ) n [ cu r ] . c . s i z e ( ) ; i++) {
10 i n t next = n [ cu r ] . c [ i ] . f i r s t ;11 i f ( n [ nex t ] . d==INF | | n [ nex t ] . d>n [ cu r ] . d+n [ cu r ] . c [ i ] . second ) {12 i f ( n [ nex t ] . d != INF )13 s . e r a s e ( make pa i r ( n [ nex t ] . d , nex t ) ) ;14 n [ nex t ] . d = n [ cu r ] . d + n [ cu r ] . c [ i ] . second ;15 s . i n s e r t ( make pa i r ( n [ nex t ] . d , nex t ) ) ;16 }17 }18 s . e r a s e ( make pa i r ( n [ cu r ] . d , cu r ) ) ;19 }20 }
Algoritmo de Dijkstra usando un set - O(N log N + E )
Training Camp Argentina 2013 Estructuras de datos
Problemas
Template Library Management (TJU - 3972): Algoritmogoloso acelerado usando dos set elegantemente.
Training Camp Argentina 2013 Estructuras de datos
Mınimo en intervalos (RMQ)
Dado un arreglo de N numeros m0, . . . ,mN−1, queremos responderpreguntas de la forma
¿Cual es el menor numero en el intervalo mi , . . . ,mj−1?≡ RMQ [i , j )
El algoritmo ingenuo recorre todos los elementos en [i , j), yrequiere O(N) en el peor caso;
Si no se van a modificar los valores del arreglo, podemospreprocesar en O(N log N) y responder preguntas en O(1);
Si los elementos del arreglo pueden cambiar, podemosinicializar en O(N) y responder preguntas o modificar valoresen O(log N)
Training Camp Argentina 2013 Estructuras de datos
RMQ - Sparse tables
Si los elementos del arreglo no pueden cambiar de valor, podemospreprocesar los datos para acelerar el calculo de las respuestas:
Hay O(N2) preguntas posibles, y podemos precalcular todassus respuestas en O(N2) usando programacion dinamica;
No hace falta guardar todas las respuestas: basta conprecalcular una cantidad suficiente como para poder respondercualquier pregunta.
Definimos
stk(i) = mini≤ j<i+2k
{mj} ≡ RMQ[i , i + 2k) para k = 0, 1, . . .
Observamos que podemos precalcular los O(N log N) valores de stusando programacion dinamica
st0(i) = mi
stk(i) = min{stk−1(i), stk−1(i + 2k−1)
}Training Camp Argentina 2013 Estructuras de datos
RMQ - Sparse tables (cont.)
Para calcular RMQ [i , j ), observamos que si 2k ≤ j − i < 2k+1,
RMQ [i , j ) = min{stk(i), stk(j − 2k)
}1 v o i d s t i n i t ( i n t ∗m, i n t N, i n t ∗∗ s t ) {2 f o r ( i n t i =0; i<N; i++) s t [ 0 ] [ i ] = m[ i ] ;3 f o r ( i n t k=1; (1<<k )<=N; k++) {4 f o r ( i n t i =0; i+(1<<k )<=N; i++) {5 i f ( s t [ k−1] [ i ] < s t [ k−1] [ i +(1<<(k−1) ) ] )6 s t [ k ] [ i ] = s t [ k−1] [ i ] ;7 e l s e s t [ k ] [ i ] = s t [ k−1] [ i +(1<<(k−1) ) ] ;8 }9 }
10 }1112 i n t s t q u e r y ( i n t ∗∗ s t , i n t s , i n t e ) {13 i n t k = 31 − b u i l t i n c l z ( e−s ) ;14 i f ( s t [ k ] [ s ] < s t [ k ] [ e−(1<<k ) ] ) r e t u r n s t [ k ] [ s ] ;15 e l s e r e t u r n s t [ k ] [ e−(1<<k ) ] ;16 }
RMQ estatico con sparse tables - O(N log N) init. y O(1) query
Training Camp Argentina 2013 Estructuras de datos
RMQ - Segment tree
Si los elementos del arreglo pueden cambiar, el preproceso oinicializacion debe ser complementado con el mantenimiento dela estructura.
Vamos a usar un arbol binario del siguiente modo:
Cada nodo representa un intervalo, en particular la raızrepresenta al [0,N)
El hijo izquierdo de un nodo representa la primera mitad delsegmento de su padre, el derecho la otra
Las hojas del arbol representan segmentos de longitud uno, yalmacenan el correspondiente valor del arreglo
En cada nodo interno se almacena el mınimo de los dosvalores almacenados en sus dos hijos
Training Camp Argentina 2013 Estructuras de datos
RMQ - Segment tree (cont.)
Una forma elegante de definir un arbol binario usando un arreglo
El “nombre” de un nodo es su posicion en el arregloLa raız es el nodo 1El hijo izquierdo de i es el nodo 2i , el derecho es el 2i + 1El padre del nodo i es el i/2El valor almacenado en el nodo es el valor en la posicioncorrespondiente del arreglo
1
10 11
100 101 110 111
1000 1001 1010 1011 1100 1101 1110 1111
Training Camp Argentina 2013 Estructuras de datos
RMQ - Segment tree (cont.)
Para inicializar, debemos llenar los valores de los nodos desdelas hojas hasta la raız: O(N)
Para modificar un valor, debemos cambiar el valor de la hojacorrespondiente y luego actualizar los valores de todos losnodos internos en el camino de la hoja hasta la raız: O(log N)
Para realizar una consulta, debemos tomar el mınimo entre losvalores almacenados en los nodos cuyos segmentoscorresponden exactamente al intervalo deseado: O(log N)
La estructura tipo arbol sugiere una implementacion recursivade todas estas funciones
Training Camp Argentina 2013 Estructuras de datos
RMQ - Segment tree (codigo)
1 #d e f i n e LEFT(n ) ( 2∗( n ) )2 #d e f i n e RIGHT(n ) ( 2∗( n )+1 )3 #d e f i n e NEUT 214748364745 i n t oper ( i n t a , i n t b ) {6 r e t u r n min ( a , b ) ;7 }89 v o i d rmq i n i t ( i n t n , i n t s , i n t e , i n t ∗rmq , i n t ∗m) {
10 i f ( s+1 == e ) rmq [ n ] = m[ s ] ;11 e l s e {12 rmq i n i t (LEFT(n ) , s , ( s+e ) /2 , rmq , m) ;13 rmq i n i t (RIGHT(n ) , ( s+e ) /2 , e , rmq , m) ;14 rmq [ n ] = oper ( rmq [ LEFT(n ) ] , rmq [RIGHT(n ) ] ) ;15 }16 }
RMQ dinamico con segment tree - Inicializacion
Training Camp Argentina 2013 Estructuras de datos
RMQ - Segment tree (codigo cont.)
1 v o i d rmq update ( i n t n , i n t s , i n t e , i n t ∗rmq , i n t ∗m, i n t p , i n tv ) {
2 i f ( s+1 == e ) rmq [ n ] = m[ s ] = v ;3 e l s e {4 i f ( p < ( s+e ) /2)5 rmq update (LEFT(n ) , s , ( s+e ) /2 , rmq , m, p , v ) ;6 e l s e rmq update (RIGHT(n ) , ( s+e ) /2 , e , rmq , m, p , v ) ;7 rmq [ n ] = oper ( rmq [ LEFT(n ) ] , rmq [RIGHT(n ) ] ) ;8 }9 }
1011 i n t rmq query ( i n t n , i n t s , i n t e , i n t ∗rmq , i n t a , i n t b ) {12 i f ( a >= e | | b <= s ) r e t u r n NEUT;13 e l s e i f ( s >= a && e <= b) r e t u r n rmq [ n ] ;14 e l s e {15 i n t l = rmq query (LEFT(n ) , s , ( s+e ) /2 , rmq , a , b ) ;16 i n t r = rmq query (RIGHT(n ) , ( s+e ) /2 , e , rmq , a , b ) ;17 r e t u r n oper ( l , r ) ;18 }19 }
RMQ dinamico con segment tree - Mantenimiento y consulta
Training Camp Argentina 2013 Estructuras de datos
RMQ - Segment tree (observaciones)
Todas las funciones se llaman con n = 1, s = 0 y e = N
En algunos casos conviene almacenar la posicion del menorelemento, en lugar de su valor
oper puede ser otras operaciones ademas de <: podemosusar >, pero tambien operaciones algebraicas como + y ∗,operaciones binarias como ∨, ∧ y |, etc.
NEUT debe ser el elemento neutro de la operacion oper
Training Camp Argentina 2013 Estructuras de datos
Suma en intervalos
Dado un arreglo de N numeros m0, . . . ,mN−1, queremos responderpreguntas de la forma
¿Cual es el valor de S [ i , j) = mi + · · ·+ mj−1?
El algoritmo ingenuo recorre todos los elementos en [i , j), yrequiere O(N) en el peor caso;
Si no se van a modificar los valores del arreglo, podemospreprocesar en O(N) y responder preguntas en O(1);
Si los elementos del arreglo pueden cambiar, podemosinicializar en O(N log N) y responder preguntas o modificarvalores en O(log N)
Training Camp Argentina 2013 Estructuras de datos
Suma en intervalos: sumas parciales
Si los elementos del arreglo no pueden modificarse, podemosprecalcular todas las respuestas en O(N2) y responder enO(1).
Observamos que basta poder responder cuando i = 0, porque
S [ i , j) = S [0, j) − S [0, i)
Luego podemos precalcular solo los valores de S [0, i) enO(N), y responder en O(1)
1 v o i d i n i t ( i n t ∗m, i n t ∗sm , i n t N) {2 sm [ 0 ] = 0 ;3 f o r ( i n t i =1; i<=N; i++) sm [ i ] = sm [ i −1]+m[ i −1] ;4 }56 i n t query ( i n t ∗sm , i n t a , i n t b ) {7 r e t u r n sm [ b]−sm [ a ] ;8 }
Suma en intervalos usando sumas parciales
Training Camp Argentina 2013 Estructuras de datos
Suma en intervalos: sumas parciales bidimensionales
El problema anterior puede generalizarse para el caso de arreglosbidimensionales: si queremos calcular
S2(a, b, c , d) =b−1∑i=a
d−1∑j=c
mij
para a < c y b < d , basta conocer S2(0, 0, i , j), dado que
S2(a, b, c , d) = S2(0, 0, c , d)−S2(0, 0, a, d)−S2(0, 0, c, b)+S2(0, 0, a, b)
Luego el preprocesamiento sera en O(N2) y las consultas en O(1).
El principio de inclusion exclusion nos permite generalizar esto aarreglos n-dimensionales, obteniendo consultas en O(2n) realizandoun preprocesamiento en O(Nn)
Training Camp Argentina 2013 Estructuras de datos
Suma en intervalos: binary indexed tree
Si los elementos del arreglo pueden modificarse, ya conocemos unaestructura eficiente: usamos un segment tree con oper 7→ + yNEUT 7→ 0.
Una estructura mas eficiente aprovecha la observacionS [ i , j) = S [0, j) − S [0, i) modificando los intervalos almacenadosen cada posicion del arreglo
Definimos bit(i) =∑i
j=i−k+1 mj con k la mayor potencia de2 que divide a i (o k = 1 si i = 0).
Para calcular S [0, i + 1) sumamos los intervalos que locomponen sacando progresivamente los 1’s de la expresionbinaria de i .
Para modificar una posicion (sumar una cantidad en unaposicion dada) agregamos la cantidad deseada a todos losintervalos que contienen esa posicion.
Training Camp Argentina 2013 Estructuras de datos
Suma en intervalos: binary indexed tree (codigo)
P. Fenwick, “A New Data Structure for Cumulative Frequency Tables”,
Software - Practice and Experience, 24(3), pp. 327-336 (1994)
1 i n t g e t c f ( i n t i dx , i n t ∗ b i t ) {2 i n t c f = b i t [ 0 ] ;3 w h i l e ( i d x > 0) {4 c f += b i t [ i d x ] ;5 i d x &= idx −1;6 }7 r e t u r n c f ;8 }9
10 v o i d upd f ( i n t i dx , i n t f , i n t ∗ b i t ) {11 i f ( i d x == 0) b i t [ i d x ] += f ;12 e l s e w h i l e ( i d x < MAXN) {13 b i t [ i d x ] += f ;14 i d x += id x&(− i d x ) ;15 }16 }
Suma en intervalos usando binary indexed tree
Training Camp Argentina 2013 Estructuras de datos
Suma en intervalos: binary indexed tree (observaciones)
Las posiciones del arreglo acumulan los cambios, luego paramodificar una posicion llamamos a upd f con
v = m(nuevo)i −m
(viejo)i
Las dos operaciones son O(log N)
La inicializacion es O(N log N) porque debemos modificartodas las posiciones una por una
Tambien puede modificarse para ser utilizado con otrasoperaciones
Se puede extender facilmente esta estructura para operarsobre arreglos bidimensionales
Training Camp Argentina 2013 Estructuras de datos
Operaciones mas generales: caso estatico
Dada una operacion asociativa ⊗ y un arreglo de N elementosm0, . . . ,mN−1 que no se pueden modificar, si queremos responderpreguntas de la forma
¿Cual es el valor de O [ i , j) = mi ⊗ · · · ⊗mj−1?
Definimos
Ok(i) =i+2k−1⊗
j=i
mj ≡ O[
i , i + 2k)
y para calcular O [ i , j) aplicamos la operacion adelantando i amedida que encontramos 1’s en la cantidad j − i
Training Camp Argentina 2013 Estructuras de datos
Operaciones mas generales: caso estatico (codigo)
1 v o i d i n i t ( i n t ∗m, i n t ∗∗sm , i n t N) {2 f o r ( i n t i =0; i<N; i++) sm [ 0 ] [ i ] = m[ i ] ;3 f o r ( i n t k=1; (1<<k )<=N; k++)4 f o r ( i n t i =0; i+(1<<k )<=N; i++)5 sm [ k ] [ i ]= oper (sm [ k−1] [ i ] , sm [ k−1] [ i +(1<<(k−1) ) ] ) ;6 }78 i n t query ( i n t ∗∗sm , i n t a , i n t b ) {9 i n t RES = 0 , l = b−a ;
10 f o r ( i n t i =0; (1<< i )<=l ; i++) i f ( l&(1<< i ) ) {11 RES = oper (RES , sm [ i ] [ a ] ) ;12 a += (1<< i ) ;13 }14 r e t u r n RES ;15 }
Operaciones mas generales: caso estatico - O(N log N) inicializaciony O(log N) consulta
Training Camp Argentina 2013 Estructuras de datos
Operaciones mas generales: caso dinamico
Si los elementos del arreglo pueden modificarse, podemos usar elsiguiente truco:
Partimos el intervalo [0,N) en√
N segmentos si coni = 0, . . . ,
√N
Para mayor comodidad, definimos ai = i√
N ybi = (i + 1)
√N; luego el i-esimo segmento corresponde a
[ai , bi ), luego
Para cada segmento, guardamos el valor de
Oi =
bi−1⊗j=ai
mj ≡ O[ai , bi )
Al realizar una modificacion en la posicion j , debemosrecalcular el Oi tal que j ∈ [ai , bi ) =⇒ O(
√N)
Al realizar una consulta, debemos realizar la operacion ⊗ sobrelos segmentos completos (a lo sumo
√N) y los elementos
sueltos a ambos lados (a lo sumo 2√
N) =⇒ O(√
N)
Training Camp Argentina 2013 Estructuras de datos
Problema adicional: ancestro comun mas bajo
El problema consiste en hallar el ancestro comun mas bajo entrepares de nodos de un arbol enraizado
Puede reducirse a la aplicacion de RMQ sobre el arreglogenerado con el pre- y post-visit DFS transversal del arbol:¿Como?
Puede pensarse como un caso particular de la estructuraanalizada para operaciones generales en arreglos estaticos:¿Como?
Puede utilizarse para calcular eficientemente distancias entrelos nodos de un arbol: ¿Como?
Training Camp Argentina 2013 Estructuras de datos
Problema adicional: ancestro comun mas bajo
El problema consiste en hallar el ancestro comun mas bajo entrepares de nodos de un arbol enraizado
Puede reducirse a la aplicacion de RMQ sobre el arreglogenerado con el pre- y post-visit DFS transversal del arbol:¿Como?
Puede pensarse como un caso particular de la estructuraanalizada para operaciones generales en arreglos estaticos:¿Como?
Puede utilizarse para calcular eficientemente distancias entrelos nodos de un arbol: ¿Como?
Training Camp Argentina 2013 Estructuras de datos
Problema adicional: ancestro comun mas bajo
El problema consiste en hallar el ancestro comun mas bajo entrepares de nodos de un arbol enraizado
Puede reducirse a la aplicacion de RMQ sobre el arreglogenerado con el pre- y post-visit DFS transversal del arbol:¿Como?
Puede pensarse como un caso particular de la estructuraanalizada para operaciones generales en arreglos estaticos:¿Como?
Puede utilizarse para calcular eficientemente distancias entrelos nodos de un arbol: ¿Como?
Training Camp Argentina 2013 Estructuras de datos
Problema adicional: ancestro comun mas bajo
El problema consiste en hallar el ancestro comun mas bajo entrepares de nodos de un arbol enraizado
Puede reducirse a la aplicacion de RMQ sobre el arreglogenerado con el pre- y post-visit DFS transversal del arbol:¿Como?
Puede pensarse como un caso particular de la estructuraanalizada para operaciones generales en arreglos estaticos:¿Como?
Puede utilizarse para calcular eficientemente distancias entrelos nodos de un arbol: ¿Como?
Training Camp Argentina 2013 Estructuras de datos