Skip to Content

Gap

Subtarea 1

Podemos hallar el mínimo y el máximo de aa en algún rango [l,r][l, r] simplemente consultando MinMax(l, r, &mn, &mx). Esto nos permite ir recortando el rango y reconstruir aa con MN+12M \leq \frac{N + 1}{2}.

Luego recorremos aa y hallamos el mayor hueco.

Subtarea 2

No necesariamente hay que reconstruir aa por completo para hallar el mayor hueco. Observemos que si conocemos una cota inferior xx de la respuesta y el rango de todos los aia_i, entonces podemos consultar el rango en bloques de tamaño x1x - 1 para hallar la respuesta. Esto funciona porque el mayor hueco siempre cubrirá al menos dos bloques.

¿Cuál es entonces la cota inferior de la respuesta? Si hay NN elementos que cubren un rango de tamaño LL, entonces la cota inferior es L+N1N1\frac{L + N - 1}{N - 1} por el principio del palomar. (Esta es una idea similar a la solución α=1/2\alpha = 1/2 de IMO 2020 P6).

Nuestro algoritmo queda así:

  • Hallar el rango que cubre aa en 1 consulta. Esto contribuye N+1N + 1 a MM.
  • Hallar xx (la cota inferior de la respuesta) con la fórmula de arriba.
  • Consultar el rango en bloques de tamaño x1x - 1. Como hay N1N - 1 de estos bloques y cada aia_i está incluido en exactamente 1 de estos bloques, esto contribuye 2N12N - 1 a MM.

Esto nos permite hallar el mayor hueco con M3NM \leq 3N.

Implementación

#include "gap.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; const ll MAXN = 1e18; ll a[100000], j = 0; ll findGap(int T, int N) { if (T == 1) { ll l = 1, r = MAXN; ll mn, mx; vector<ll> v; for (ll i = 0; i < (N + 1) / 2; i++) { MinMax(l, r, &mn, &mx); a[j++] = mn; a[j++] = mx; l = mn + 1, r = mx - 1; } sort(a, a + N); ll ans = 0; for (ll i = 0; i < N - 1; i++) ans = max(ans, a[i + 1] - a[i]); return ans; } else { ll mn, mx; MinMax(1, MAXN, &mn, &mx); ll step = (mx - mn + N - 2) / (N - 1); ll ans = step, x, y, l = mn, i; for (i = mn; i + step < mx; i += step + 1) { MinMax(i, i + step, &x, &y); if (x != -1) { ans = max(ans, x - l); l = y; } } MinMax(i, mx, &x, &y); if (x != -1) ans = max(ans, x - l); return ans; } }