Para este problema, consideramos un arreglo de ocurrencias sobre los elementos del arreglo. De modo que la respuesta está dada por
Si consideramos el mismo arreglo de ocurrencias sobre los elementos del arreglo, la respuesta está dada por
.
Podemos generar todos los elementos de la secuencia de Fibonacci hasta , y guardarlos en un mapa
, de modo que
si
es un elemento de Fibonnaci, y
en caso contrario. Generamos la respuesta simplemente iterando desde
hasta
, e imprimimos
si
.
La clave para este problema, es usar variables que no provoquen un desbordamiento, por ejemplo, unsigned long long. Luego, es conocido que la serie de Fibonacci crece rápidamente, lo suficiente, como para generar la secuencia con todos sus elementos menores o iguales a , guardando por cada uno su respectiva posición en ella. Por lo tanto, basta con checar si
es un elemento, e imprimir su posición. En caso de no serlo, imprimimos
.
Este tipo de problema es conocido como straight-forward. Podemos guardar las estaciones de radio, y checar cuál estación es la mas cercana a la frecuencia dada, con una simple resta. En caso de haber dos estaciones con la misma distancia, la respuesta es la mayor. Solo debemos cuidar que la frecuencia esté dentro del rango permitido.
En este problema lo que tenemos es un grafo dirigido acíclico con aristas pesadas (intuitivamente, es un árbol, sin la propiedad de que cualquier par de nodos estan conectados por un único camino).
Los vértices son los eventos temporales, las aristas son dirigidas de a
, y su peso es
. Además, cada vértice contiene un valor extra
. Un grafo que podemos asociar al primer caso de ejemplo es el siguiente.
Sean y
dos vértices distintos, tales que
es ancestro de
. Es decir, existe un camino
en el grafo. Definimos
como
Es decir, la suma de los pesos en las aristas del camino.
De modo que el problema se convierte en: Para cada vertice , contar cuántos vértices
en su “subárbol”
existen tales que
Porque esto siginifica que tenemos suficientes segundos para viajar por el tiempo desde hasta
.
Consideremos un arreglo , donde la entrada
guarda cuántos descendientes
de
satisfacen
Pero
Donde es el padre de
. Si
, entonces no hace falta considerar a su padre, puesto que no podemos viajar por el tiempo a algún ancestro de
(ya que ni siquiera existe alguno).
En otras palabras, guarda cuántos descendientes de
llegan a lo mas al vértice
.
También consideremos un arreglo , donde la entrada
guarda cuántos descendientes
de
satisfacen
Es decir, guarda cuántos descendientes de
no pueden llegar al vertice
.
Y además mantengamos un arreglo , donde la entrada
guarda el tamaño del “subárbol” de
(incluyendo a
). En otras palabras, cuántos descendientes tiene
en total mas el mismo.
Por lo tanto, la respuesta final para el vértice está dada por
donde es un hijo directo de
.
Ya que esto calcula cuántos descendientes de si pueden llegar a
.
Para el cálculo de nuestros arreglos, hacemos una dfs sobre el “árbol” (partiendo del vertice 0). Para cada vértice , hacemos una búsqueda binaria sobre un arreglo que mantenga la suma acumulada de los costos sobre las aristas que forman parte del camino de
a
, que nos devuelva el máximo ancestro
al que podemos llegar desde
. Lo que nos dice que
actualiza su valor a
(inicialmente,
). Esto se puede hacer usando un arreglo global. La idea es añadir la suma acumulada, luego explorar recursivamente el subárbol de
, y luego quitar la suma acumulada que añadimos. Esto es particularmente sencillo si usamos un vector de la STL para el arreglo global.
El arreglo se calcula facilmente en la misma dfs, ya que
Ahora podemos generar , al estilo de programacion dinámica usando
. Notemos que
Lo que se puede hacer en la misma DFS.
Por lo tanto, nuestro algoritmo tiene complejidad .
Primero reescribamos la expresión dada como
De donde podemos despejar como
Sin perdida de generalidad, supongamos , entonces se tiene
Por lo tanto, podemos iterar desde
hasta
, obtenemos
, y verificamos que
.
Guardamos las parejas que satisfazcan dichas condiciones y las imprimimos en el orden requerido, cuidando no repetir alguna respuesta.
Lo que nos deja con un algoritmo de complejidad .
Una solución alternativa es la siguiente:
Te puedes dar cuenta que , entonces el problema se convierte a buscar
y
que cumplan
con . Si simplificas la igualdad llegas a que
, así que todo se reduce a encontrar las parejas de divisores
de
. Lo que deja también un algoritmo de complejidad
.
Nota: Agradezco a José Tapia y a Carlos Galeana por su colaboración en el problema .