Tabla de contenido
1. Tubería
1. Descripción del problema
Hay una longitud de len \text{len}La tubería horizontal de len se divide en len \text{len}Segmentos len , cada segmento tiene una válvula conmutable y un sensor para detectar el flujo de agua en el centro.
Inicialmente la tubería está vacía y ubicada en L i L_ilyoLa válvula estará en S i S_iSyoDéjelo abierto en todo momento y mantenga el agua fluyendo hacia la tubería.
Para L i L_ilyoválvula, el agua por la que fluye está en T i T_ityo( T i ≥ S i T_i \geq S_ityo≥Syo) momento hará que el punto de partida sea L i − ( T i − S i ) L_i - (T_i - S_i)lyo−( tyo−Syo) etapaLi + ( T i − Si ) L_i + (T_i - S_i)lyo+( tyo−Syo) el sensor de segmento detecta el flujo de agua.
Encuentre el momento más temprano en el que el sensor en el medio de cada sección de la tubería detecta el flujo de agua.
2. Formato de entrada
La primera línea de entrada contiene dos números enteros n, len n,\text{len}norte ,len , separados por un espacio, representan respectivamente el número de válvulas que se abrirán y la longitud de la tubería.
siguientenn _Cada línea de n líneas contiene dos números enteros L i , S i L_i,S_ilyo,Syo, separados por un espacio, indica que está ubicado en L i L_ilyoLa válvula en el centro del segmento de tubería estará en S i S_iSyoSiempre abierto.
3. Formato de salida
Una línea de salida contiene un número entero que representa la respuesta.
4. Entrada de muestra
3 10
1 1
6 5
10 2
5. Salida de muestra
5
6. Escala de casos de uso y convenciones de evaluación
por 30 3030 % de los casos de evaluación,n ≤ 200 n \leq 200norte≤200,S i , len ≤ 3000 S_i, \text{len} \leq 3000Syo,len≤3000;
por 70 7070 % de los casos de evaluación,n ≤ 5000 n \leq 5000norte≤5000,S i , len ≤ 1 0 5 S_i, \text{len} \leq 10^5Syo,len≤1 05;
Para todos los casos de evaluación, 1 ≤ n ≤ 1 0 5 1 \leq n \leq 10^51≤norte≤1 05 ,1 ≤ S i , len ≤ 1 0 9 1 \leq S_i,\text{len} \leq 10^91≤Syo,len≤1 09 ,1 ≤ L i ≤ len 1 \leq L_i \leq \text{len}1≤lyo≤len , L i − 1 < L i L_{i-1} < L_ilyo − 1<lyo。
2. Ideas para resolver problemas
Para un momento xxx , si todos los sensores pueden detectar el flujo de agua en este momento, entonces cuando el punto de tiempo sea mayor quexxCuando x , también se debe garantizar que todos los sensores puedan detectar el flujo de agua. La pregunta requiere que encontremos el punto temporal más pequeño que cumpla las condiciones. Como la respuesta es bipartita, podemos pensar en una respuesta dicotómica.
Después de tener la idea dicotómica, el problema se convierte a un determinado momento xx.x , ¿cómo juzgamos que todos los sensores pueden detectar el flujo de agua en este momento? Piense detenidamente, cuando se determine el tiempo, para una persona ubicada enai a_iayoY el tiempo de apertura es S i ( S i ≤ x ) S_i(S_i \leq x)Syo( syo≤x ) , su flujo de agua es en realidad un intervalo de cobertura[ ai − ( x − S i ) , ai + ( x − S i ) ] [a_i-(x-S_i),a_i+(x-S_i)][ unyo−( x−Syo) ,ayo+( x−Syo)] segmento de línea.
Podemos tomar todos los S i ≤ x S_i \leq xSyo≤Todas las válvulas de x se convierten y lo que realmente se obtiene son varios segmentos de línea. Determinar si todos los sensores pueden detectar el flujo de agua equivale a determinar si estos diversos segmentos de línea pueden cubrir el intervalo[1, len] [1,\text{len}][ 1 ,len ] , el problema se transforma en un problema de cobertura de intervalo.
La cobertura de intervalos es un problema clásico. Podemos ordenar estos intervalos por su punto final izquierdo. A continuación comprobamos si estos intervalos cubren todo el oleoducto. Si el punto final izquierdo del primer intervalo es mayor que 1 11 , entonces significa que el inicio del oleoducto no está cubierto y regresa directamentefalse
. De lo contrario configuramos una variablerrr representa la distancia más lejana alcanzable,rrEl valor inicial de r es el punto final derecho del primer intervalo. Luego comprobamos si otros intervalos son consistentes conrrr adyacentes o superpuestos. Si el intervalo actual yrrr es adyacente o se superpone, agregamos el punto final derecho del intervalo actual yrr toma el valor máximo. Finalmente sir ≥ len r \geq \text{len}r≥len significa que todos los intervalos se cubren con éxito; de lo contrario, significa que no.
Volvamos atrás y consideremos cómo escribir dicotomía .l es el límite inferior de la respuesta,rrr es el límite superior de la respuesta. Si el punto temporal obtenido por dicotomía esmid \text{mid}mid es elegible porque es mayor quemid \text{mid}El punto de tiempo de mid también debe cumplir las condiciones, por lo que actualicer = mid r=\text{mid}r=mid , de lo contrario actualicel = mid+1 l=\text{mid+1}yo=medio+1 . Repetimos este proceso hasta que los extremos izquierdo y derecho del rango de búsqueda sean iguales, momento en el que se encuentra el momento más temprano. Por supuestol,rl,ryo ,También debemos pensar en el valor inicial de r , llobviamente soy 1 11 , mientras querrrNecesitamos considerar la situación límite, es decir, solo hay una válvula más a la izquierda o más a la derecha que se abre en el último momento. Obviamente, el tiempo requerido en este momento es2 × 1 0 9 2 \times 10^92×1 09 , entoncesrrEl valor inicial de r es 2 × 1 0 9 2 \times 10^92×1 09 .
Complejidad del tiempo: O ( n log n 2 ) O(n\log n^2)O ( n.iniciar sesiónnorte2 )。
3. Código_AC
- C++
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define sz(s) ((int)s.size())
int n, m;
int main()
{
ios_base :: sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> m;
vector<int> a(n), s(n);
for (int i = 0; i < n; ++i) {
cin >> a[i] >> s[i];
}
auto check = [&](LL t) {
std::vector<pair<LL, LL>> v;
for (int i = 0; i < n; ++i) {
if (t >= s[i]) v.push_back({
a[i] - (t - s[i]), a[i] + (t - s[i])});
}
sort(v.begin(), v.end());
if (sz(v) == 0 || v[0].first > 1) return false;
LL r = v[0].second;
for (int i = 1; i < sz(v); ++i) {
if (v[i].first <= r + 1) r = max(r, v[i].second);
else break;
}
return r >= m;
};
LL l = 1, r = 2e9;
while (l < r) {
LL mid = l + r >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
cout << r << '\n';
return 0;
}
- Java
import java.util.*;
public class Main {
static int n, m;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
int[] a = new int[n];
int[] s = new int[n];
for (int i = 0; i < n; ++i) {
a[i] = sc.nextInt();
s[i] = sc.nextInt();
}
long l = 1, r = 2_000_000_000;
while (l < r) {
long mid = l + r >>> 1;
if (check(mid, a, s)) r = mid;
else l = mid + 1;
}
System.out.println(r);
}
private static boolean check(long t, int[] a, int[] s) {
List<Pair<Long, Long>> v = new ArrayList<>();
for (int i = 0; i < n; ++i) {
if (t >= s[i]) {
v.add(new Pair<>(a[i] - (t - s[i]), a[i] + (t - s[i])));
}
}
v.sort(Comparator.comparingLong(Pair::getKey));
if (v.size() == 0 || v.get(0).getKey() > 1) return false;
long r = v.get(0).getValue();
for (int i = 1; i < v.size(); ++i) {
if (v.get(i).getKey() <= r + 1) r = Math.max(r, v.get(i).getValue());
else break;
}
return r >= m;
}
static class Pair<K, V> {
private final K key;
private final V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
}
}
- Pitón
n, m = map(int, input().split())
a = []
s = []
for i in range(n):
a_i, s_i = map(int, input().split())
a.append(a_i)
s.append(s_i)
def check(t):
v = []
for i in range(n):
if t >= s[i]:
v.append((a[i] - (t - s[i]), a[i] + (t - s[i])))
v.sort()
if len(v) == 0 or v[0][0] > 1:
return False
r = v[0][1]
for i in range(1, len(v)):
if v[i][0] <= r + 1:
r = max(r, v[i][1])
else:
break
return r >= m
l = 1
r = 2_000_000_000
while l < r:
mid = (l + r) // 2
if check(mid):
r = mid
else:
l = mid + 1
print(r)