Estructura/Wavelet Tree o Segment Trees
Solución 1
Este problema requiere conocimiento de una estructura llamada Wavelet Tree. Permite responder a la pregunta "cual es el $k$-ésimo menor elemento en el intervalo $[i,j]$ de un arreglo dado?" en $O(\log{}n)$.
Esta estructura puede ser usada para resolver el problema "Batata Quente" de la primera fase de la maratona de Brasil (
http://maratona.ime.usp.br/prim-fase16/maratona.pdf) en $O(n\log{}n)$ (La solución oficial tenía complejidad de $O(n \sqrt{n}\log{}n)$, usando sqrt decomposition.)
Hay una explicación disponible en Quora:
https://www.quora.com/How-can-you-build-a-data-structure-on-an-array-that-returns-kth-order-statistics-on-subarrays-in-logarithmic-time.
También se encuentra descripta en el paper de los autores, que también explican como hacer la actualización de intercambiar dos elementos adyacentes (es muy simple):
https://www.dcc.uchile.cl/~jperez/papers/ioiconf16.pdf.
Solución 2
Existe otra solución posible para responder la misma query de los Wavelet Trees en $O(\log^2{}n)$, que consiste en construir un segment tree sobre el rango de valores. Por ejemplo, si el arreglo $V$ es $V[0]=2, V[1]=0, V[2]=1, V[3]=2, V[4]=3$, entonces en la hojas guardaremos $hoja[0]=\{1\}, hoja[1]=\{2\}, hoja[2]=\{0, 3\}, hoja[3]=\{4\}$ (una especie de inversión del arreglo). La operación del segment tree va a ser la unión (sobre multiset) y para responder las queries debemos usar búsqueda binaria sobre cada nodo.
Nota: No es necesario codearse un árbol balanceado, podemos usar la STL (ver:
http://codeforces.com/blog/entry/11080)
Solución 3
Es posible hacer otra solución utilizando segment trees persistentes y contestar la query en $O(\log{}n)$. Esta solución alternativa fue explicada por Victor Agnez en el blog de FFAO (la cual inspiró la explicación que sigue). El código está disponible en:
http://ideone.com/HdOhu1.
Para facilitar la explicación, primero vamos a considerar un problema más simple: a partir de un arreglo de números, mantener un segment tree que responda cuantos elementos con valor entre $a$ y $b$ existen. Esto es fácil, construimos un segment tree donde la hoja $i$-ésima guarda la cantidad de veces que el número $i$ aparece en el arreglo. Utilizamos la operación suma para construir el segment tree. Lo que tenemos es que cada nodo representando el rango $[a, b]$ nos dice cuantos valores hay en ese rango.
En este segment tree es fácil buscar el $K$-ésimo menor elemento: lo hacemos recorriendo el árbol desde la raíz. Suponiendo que estamos en el nodo que representa el intervalo [a,b], el hijo izquierdo contiene la cantidad de elementos en el rango $[a, \frac{a+b}{2}]$. Si esa cantidad es menor o igual a $K$, entonces el $K$-ésimo menor elemento se encuentra en el hijo izquierdo. De lo contrario, el $K$-ésimo menor está en el hijo derecho. Si llegamos a una hoja, encontramos el $K$-ésimo.
Volviendo al problema E: vamos a suponer que para cada prefijo del arreglo, tenemos ese segment tree. Ahora, si miramos el $j$-ésimo segment tree y un nodo dentro del mismo representando el intervalo $[a, b]$, él mismo va a tener guardado cuantos valores en el rango $[a, b]$ hay en las posiciones $[0, j]$ del arreglo original. La clave de esta solución está en notar que si un nodo del $j$-ésimo segment tree guarda cuantos hay en el intervalo $[0, j]$, podemos restarle el mismo nodo pero del $(i-1)$-ésimo segment tree y obtener cuantos hay en el intervalo $[i, j]$ (es decir tomamos cuantos hay en o antes de $j$ pero le restamos los que aparecen antes de $i$). Es decir que, restando nodo a nodo el $j$-ésimo y el $(i-1)$-ésimo segment tree, puedo obtener un nuevo segment tree que me cubriría sólo el subarreglo $[i, j]$. Recorriendo este segment tree, puedo encontrar el $K$-ésimo menor de la misma forma ya explicada. El detalle está en que no es necesario crearse el nuevo segment tree entero, basta con ir haciendo la restas entre los dos árboles a medida que voy necesitando los valores.
Por último, notar que el $i$-ésimo segment tree es muy semejante al segment tree de prefijo $(i-1)$: apenas se agrega un elemento (sólo se hizo una operación de modificación). Por lo que utilizando persistencia (que aprovecha la memoria en común entre los árboles) podemos efectivamente tener los árboles de todos los prefijos.