题 解 【CF1338A con alimentación adicional】

\ [\ texttt {Descripción} \]

Dé una secuencia \ (a \) de longitud \ (n \) .

Para el segundo \ (i \) segundo, podemos elegir el número en varias posiciones más \ (2 ^ {i-1} \) .

Pregunte al menos unos segundos, puede hacer \ (a_1 \ leq a_2 \ leq ... \ leq a_n \) .

\ [\ texttt {Solución} \]

  • No es difícil notar primero que durante los primeros \ (i \) segundos, podemos agregar \ (x \ en [1,2 ^ i-1] \) a un número .

  • En otras palabras, durante los primeros \ (i \) segundos, podemos convertir un número \ (x \) en cualquier número en \ ([x, x + 2 ^ i-1] \) .

  • Considere esta ecuación \ (A_1 \ Leq A_2 \ Leq ... \ Leq a_n \) , obviamente, \ (a_i \) es más pequeño, \ (a_ {i + 1} \) a \ (a_n \) más Hay "espacio de operación".

  • Y debido a que la operación solo hará que el número sea mayor, obviamente no queremos mover esto \ (a_1 \) .

  • Entonces considere \ (a_2 \) :

    • Si \ (a_1 \ leq a_2 \) , se han cumplido los requisitos del problema para dejar "espacio de operación" para los siguientes números, así que no lo mueva.
    • Si \ (a_1> a_2 \) , entonces se cumple la dicotomía mínima \ (x \) \ (a_1 \ leq a_2 + 2 ^ x-1 \) , use \ (x \) para actualizar la respuesta, y luego haga \ (a_2 = a_1 \) .
  • Por analogía, consideramos \ (a_3, a_4, ..., a_n \) , suponiendo que ahora consideremos la posición \ (i \) :

    • Si \ (a_ {i-1} \ leq a_i \) , entonces se han cumplido los requisitos del problema, para dejar "espacio de operación" para los siguientes números, así que no lo mueva.
    • Si \ (a_ {i-1}> a_i \) , entonces se cumple la dicotomía mínima \ (x \) \ (a_ {i-1} \ leq a_i + 2 ^ x-1 \) , use \ (x \) Actualice la respuesta y luego haga \ (a_i = a_ {i-1} \) .
  • De esta manera , la respuesta se puede encontrar después de considerar los bits \ (n \) , \ (\ mathcal {O (n \ log \ log size)} \) , donde \ (size \) representa el tamaño del rango.

\ [\ texttt {Code} \]

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

namespace IO {
    static char buf[1 << 20], *fs, *ft;
    inline char gc() {
        if (fs == ft) {
			ft = (fs = buf) + fread(buf, 1, 1 << 20, stdin);
			if (fs == ft) return EOF;
        }
        return *fs ++;
    }
    #define gc() getchar()
	inline int read() {
		int x = 0, f = 1; char s = gc();
		while (s < '0' || s > '9') {if (s == '-') f = -f; s = gc();}
		while (s >= '0' && s <= '9') {x = x * 10 + s - '0'; s = gc();}
		return x * f;
	}
} using IO :: read;

const int N = 200100; 

int n;

long long a[N];

void work() {

	n = read();

	for (int i = 1; i <= n; i ++)
		a[i] = read();

	int ans = 0;

	for (int i = 2; i <= n; i ++) {
		if (a[i - 1] <= a[i]) continue;

		int l = 1, r = 33;
		while (l < r) {
			int mid = (l + r) / 2;
			long long delta = (1ll << mid) - 1;

			if (a[i - 1] <= a[i] + delta) r = mid; else l = mid + 1; 
		}

		ans = max(ans, l);

		a[i] = a[i - 1]; 
	}

	printf("%d\n", ans);
}

int main() {

	int T = read();

	while (T --)    work();

	return 0;
}

\ [\ texttt {Gracias} \ \ texttt {por} \ \ texttt {viendo} \]

Supongo que te gusta

Origin www.cnblogs.com/cjtcalc/p/12688959.html
Recomendado
Clasificación