Submission #1221409

#TimeUsernameProblemLanguageResultExecution timeMemory
1221409juaquin_remonMobile (BOI12_mobile)C++20
0 / 100
258 ms51136 KiB
#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ld = long double;
const ld INF = 1e30L;

struct Station {
    ld x, y2;  // guardamos y² para simplificar f_i(x) = (x−x_i)² + y_i²
};

// Calcula el punto x en el que f_j(x) = f_i(x)
// con f_k(x) = (x − x_k)² + y_k² .
// Asumimos x_j != x_i.
ld intersectX(const Station &i, const Station &j) {
    // (x−x_j)² + y_j² = (x−x_i)² + y_i²
    // → x = ((y_i² + x_i²) − (y_j² + x_j²)) / (2(x_i − x_j))
    return ((i.y2 + i.x*i.x) - (j.y2 + j.x*j.x)) / (2*(i.x - j.x));
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    ll N;
    ld L;
    cin >> N >> L;

    vector<Station> a(N);
    for(int i = 0; i < N; i++){
        ll xi, yi;
        cin >> xi >> yi;
        a[i].x  = xi;
        a[i].y2 = (ld)yi * yi;
    }
    // Suponemos que ya vienen ordenadas por x; si no:
    // sort(a.begin(), a.end(), [](auto &A, auto &B){ return A.x < B.x; });

    // Encolamos los índices de las estaciones en el hull
    vector<int> hull;
    // Y guardamos los puntos de corte con la estación anterior en el hull
    vector<ld> cuts;
    hull.reserve(N);
    cuts.reserve(N);

    for(int i = 0; i < N; i++){
        // Eliminamos de atrás mientras la intersección
        // con el nuevo sea <= la última intersección
        while(!hull.empty()){
            int j = hull.back();
            ld xij = intersectX(a[j], a[i]);
            if(cuts.empty() || xij > cuts.back()){
                // vale, es un punto de corte válido creciente
                cuts.push_back(xij);
                break;
            }
            // si no, descartamos j
            hull.pop_back();
            cuts.pop_back();
        }
        // si el hull estaba vacío, empujamos la estación sin corte previo
        if(hull.empty()){
            hull.push_back(i);
            // usamos un “corte” ficticio = −∞ para el primer segmento
            cuts.push_back(-INF);
        } else {
            hull.push_back(i);
        }
    }

    // Ahora tenemos K = hull.size() estaciones activas y K cortes
    int K = hull.size();
    ld ans2 = 0;  // guardaremos el máximo de dist²

    for(int t = 0; t < K; t++){
        int i = hull[t];
        // Intervalo de validez de esta estación:
        // [ left, right ] ∩ [0, L]
        ld left  = t == 0     ? 0 : cuts[t];
        ld right = t+1 == K   ? L : cuts[t+1];

        // recortamos al dominio [0, L]
        left  = max(left,  (ld)0);
        right = min(right, L);

        if(left > right) continue;

        // La distancia mínima en este segmento se da siempre
        // en uno de los extremos (porque f_i es parábola convexa)
        ld dx1 = left  - a[i].x;
        ld dx2 = right - a[i].x;
        ans2 = max(ans2, dx1*dx1 + a[i].y2);
        ans2 = max(ans2, dx2*dx2 + a[i].y2);
    }

    // la respuesta es sqrt(del dist²)
    ld ans = sqrtl(ans2);
    cout << fixed << setprecision(6) << (double)ans << "\n";
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...