QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#304189#8007. Egg Drop Challengeucup-team087#WA 10ms4792kbC++2020.3kb2024-01-13 16:20:302024-01-13 16:20:31

Judging History

你现在查看的是最新测评结果

  • [2024-01-13 16:20:31]
  • 评测
  • 测评结果:WA
  • 用时:10ms
  • 内存:4792kb
  • [2024-01-13 16:20:30]
  • 提交

answer

#line 1 "library/my_template.hpp"
#if defined(LOCAL)
#include <my_template_compiled.hpp>
#else
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using u32 = unsigned int;
using u64 = unsigned long long;
using i128 = __int128;
using u128 = unsigned __int128;
using f128 = __float128;

template <class T>
constexpr T infty = 0;
template <>
constexpr int infty<int> = 1'000'000'000;
template <>
constexpr ll infty<ll> = ll(infty<int>) * infty<int> * 2;
template <>
constexpr u32 infty<u32> = infty<int>;
template <>
constexpr u64 infty<u64> = infty<ll>;
template <>
constexpr i128 infty<i128> = i128(infty<ll>) * infty<ll>;
template <>
constexpr double infty<double> = infty<ll>;
template <>
constexpr long double infty<long double> = infty<ll>;

using pi = pair<ll, ll>;
using vi = vector<ll>;
template <class T>
using vc = vector<T>;
template <class T>
using vvc = vector<vc<T>>;
template <class T>
using vvvc = vector<vvc<T>>;
template <class T>
using vvvvc = vector<vvvc<T>>;
template <class T>
using vvvvvc = vector<vvvvc<T>>;
template <class T>
using pq = priority_queue<T>;
template <class T>
using pqg = priority_queue<T, vector<T>, greater<T>>;

#define vv(type, name, h, ...) \
  vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...)   \
  vector<vector<vector<type>>> name( \
      h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...)       \
  vector<vector<vector<vector<type>>>> name( \
      a, vector<vector<vector<type>>>(       \
             b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))

// https://trap.jp/post/1224/
#define FOR1(a) for (ll _ = 0; _ < ll(a); ++_)
#define FOR2(i, a) for (ll i = 0; i < ll(a); ++i)
#define FOR3(i, a, b) for (ll i = a; i < ll(b); ++i)
#define FOR4(i, a, b, c) for (ll i = a; i < ll(b); i += (c))
#define FOR1_R(a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR2_R(i, a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR3_R(i, a, b) for (ll i = (b)-1; i >= ll(a); --i)
#define overload4(a, b, c, d, e, ...) e
#define overload3(a, b, c, d, ...) d
#define FOR(...) overload4(__VA_ARGS__, FOR4, FOR3, FOR2, FOR1)(__VA_ARGS__)
#define FOR_R(...) overload3(__VA_ARGS__, FOR3_R, FOR2_R, FOR1_R)(__VA_ARGS__)

#define FOR_subset(t, s) \
  for (ll t = (s); t >= 0; t = (t == 0 ? -1 : (t - 1) & (s)))
#define all(x) x.begin(), x.end()
#define len(x) ll(x.size())
#define elif else if

#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define fi first
#define se second

#define stoi stoll

int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(ll x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }
int popcnt_mod_2(int x) { return __builtin_parity(x); }
int popcnt_mod_2(u32 x) { return __builtin_parity(x); }
int popcnt_mod_2(ll x) { return __builtin_parityll(x); }
int popcnt_mod_2(u64 x) { return __builtin_parityll(x); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2)
int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2)
int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }

template <typename T>
T floor(T a, T b) {
  return a / b - (a % b && (a ^ b) < 0);
}
template <typename T>
T ceil(T x, T y) {
  return floor(x + y - 1, y);
}
template <typename T>
T bmod(T x, T y) {
  return x - y * floor(x, y);
}
template <typename T>
pair<T, T> divmod(T x, T y) {
  T q = floor(x, y);
  return {q, x - q * y};
}

template <typename T, typename U>
T SUM(const vector<U> &A) {
  T sm = 0;
  for (auto &&a: A) sm += a;
  return sm;
}

#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define LB(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define UB(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) \
  sort(all(x)), x.erase(unique(all(x)), x.end()), x.shrink_to_fit()

template <typename T>
T POP(deque<T> &que) {
  T a = que.front();
  que.pop_front();
  return a;
}
template <typename T>
T POP(pq<T> &que) {
  T a = que.top();
  que.pop();
  return a;
}
template <typename T>
T POP(pqg<T> &que) {
  T a = que.top();
  que.pop();
  return a;
}
template <typename T>
T POP(vc<T> &que) {
  T a = que.back();
  que.pop_back();
  return a;
}

template <typename F>
ll binary_search(F check, ll ok, ll ng, bool check_ok = true) {
  if (check_ok) assert(check(ok));
  while (abs(ok - ng) > 1) {
    auto x = (ng + ok) / 2;
    (check(x) ? ok : ng) = x;
  }
  return ok;
}
template <typename F>
double binary_search_real(F check, double ok, double ng, int iter = 100) {
  FOR(iter) {
    double x = (ok + ng) / 2;
    (check(x) ? ok : ng) = x;
  }
  return (ok + ng) / 2;
}

template <class T, class S>
inline bool chmax(T &a, const S &b) {
  return (a < b ? a = b, 1 : 0);
}
template <class T, class S>
inline bool chmin(T &a, const S &b) {
  return (a > b ? a = b, 1 : 0);
}

// ? は -1
vc<int> s_to_vi(const string &S, char first_char) {
  vc<int> A(S.size());
  FOR(i, S.size()) { A[i] = (S[i] != '?' ? S[i] - first_char : -1); }
  return A;
}

template <typename T, typename U>
vector<T> cumsum(vector<U> &A, int off = 1) {
  int N = A.size();
  vector<T> B(N + 1);
  FOR(i, N) { B[i + 1] = B[i] + A[i]; }
  if (off == 0) B.erase(B.begin());
  return B;
}

// stable sort
template <typename T>
vector<int> argsort(const vector<T> &A) {
  vector<int> ids(len(A));
  iota(all(ids), 0);
  sort(all(ids),
       [&](int i, int j) { return (A[i] == A[j] ? i < j : A[i] < A[j]); });
  return ids;
}

// A[I[0]], A[I[1]], ...
template <typename T>
vc<T> rearrange(const vc<T> &A, const vc<int> &I) {
  vc<T> B(len(I));
  FOR(i, len(I)) B[i] = A[I[i]];
  return B;
}
#endif
#line 1 "library/other/io.hpp"
#define FASTIO
#include <unistd.h>

// https://judge.yosupo.jp/submission/21623
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf
uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
  char num[10000][4];
  constexpr Pre() : num() {
    for (int i = 0; i < 10000; i++) {
      int n = i;
      for (int j = 3; j >= 0; j--) {
        num[i][j] = n % 10 | '0';
        n /= 10;
      }
    }
  }
} constexpr pre;

inline void load() {
  memcpy(ibuf, ibuf + pil, pir - pil);
  pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
  pil = 0;
  if (pir < SZ) ibuf[pir++] = '\n';
}

inline void flush() {
  fwrite(obuf, 1, por, stdout);
  por = 0;
}

void rd(char &c) {
  do {
    if (pil + 1 > pir) load();
    c = ibuf[pil++];
  } while (isspace(c));
}

void rd(string &x) {
  x.clear();
  char c;
  do {
    if (pil + 1 > pir) load();
    c = ibuf[pil++];
  } while (isspace(c));
  do {
    x += c;
    if (pil == pir) load();
    c = ibuf[pil++];
  } while (!isspace(c));
}

template <typename T>
void rd_real(T &x) {
  string s;
  rd(s);
  x = stod(s);
}

template <typename T>
void rd_integer(T &x) {
  if (pil + 100 > pir) load();
  char c;
  do
    c = ibuf[pil++];
  while (c < '-');
  bool minus = 0;
  if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
    if (c == '-') { minus = 1, c = ibuf[pil++]; }
  }
  x = 0;
  while ('0' <= c) { x = x * 10 + (c & 15), c = ibuf[pil++]; }
  if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
    if (minus) x = -x;
  }
}

void rd(int &x) { rd_integer(x); }
void rd(ll &x) { rd_integer(x); }
void rd(i128 &x) { rd_integer(x); }
void rd(u32 &x) { rd_integer(x); }
void rd(u64 &x) { rd_integer(x); }
void rd(u128 &x) { rd_integer(x); }
void rd(double &x) { rd_real(x); }
void rd(long double &x) { rd_real(x); }
void rd(f128 &x) { rd_real(x); }

template <class T, class U>
void rd(pair<T, U> &p) {
  return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T>
void rd_tuple(T &t) {
  if constexpr (N < std::tuple_size<T>::value) {
    auto &x = std::get<N>(t);
    rd(x);
    rd_tuple<N + 1>(t);
  }
}
template <class... T>
void rd(tuple<T...> &tpl) {
  rd_tuple(tpl);
}

template <size_t N = 0, typename T>
void rd(array<T, N> &x) {
  for (auto &d: x) rd(d);
}
template <class T>
void rd(vc<T> &x) {
  for (auto &d: x) rd(d);
}

void read() {}
template <class H, class... T>
void read(H &h, T &... t) {
  rd(h), read(t...);
}

void wt(const char c) {
  if (por == SZ) flush();
  obuf[por++] = c;
}
void wt(const string s) {
  for (char c: s) wt(c);
}
void wt(const char *s) {
  size_t len = strlen(s);
  for (size_t i = 0; i < len; i++) wt(s[i]);
}

template <typename T>
void wt_integer(T x) {
  if (por > SZ - 100) flush();
  if (x < 0) { obuf[por++] = '-', x = -x; }
  int outi;
  for (outi = 96; x >= 10000; outi -= 4) {
    memcpy(out + outi, pre.num[x % 10000], 4);
    x /= 10000;
  }
  if (x >= 1000) {
    memcpy(obuf + por, pre.num[x], 4);
    por += 4;
  } else if (x >= 100) {
    memcpy(obuf + por, pre.num[x] + 1, 3);
    por += 3;
  } else if (x >= 10) {
    int q = (x * 103) >> 10;
    obuf[por] = q | '0';
    obuf[por + 1] = (x - q * 10) | '0';
    por += 2;
  } else
    obuf[por++] = x | '0';
  memcpy(obuf + por, out + outi + 4, 96 - outi);
  por += 96 - outi;
}

template <typename T>
void wt_real(T x) {
  ostringstream oss;
  oss << fixed << setprecision(15) << double(x);
  string s = oss.str();
  wt(s);
}

void wt(int x) { wt_integer(x); }
void wt(ll x) { wt_integer(x); }
void wt(i128 x) { wt_integer(x); }
void wt(u32 x) { wt_integer(x); }
void wt(u64 x) { wt_integer(x); }
void wt(u128 x) { wt_integer(x); }
void wt(double x) { wt_real(x); }
void wt(long double x) { wt_real(x); }
void wt(f128 x) { wt_real(x); }

template <class T, class U>
void wt(const pair<T, U> val) {
  wt(val.first);
  wt(' ');
  wt(val.second);
}
template <size_t N = 0, typename T>
void wt_tuple(const T t) {
  if constexpr (N < std::tuple_size<T>::value) {
    if constexpr (N > 0) { wt(' '); }
    const auto x = std::get<N>(t);
    wt(x);
    wt_tuple<N + 1>(t);
  }
}
template <class... T>
void wt(tuple<T...> tpl) {
  wt_tuple(tpl);
}
template <class T, size_t S>
void wt(const array<T, S> val) {
  auto n = val.size();
  for (size_t i = 0; i < n; i++) {
    if (i) wt(' ');
    wt(val[i]);
  }
}
template <class T>
void wt(const vector<T> val) {
  auto n = val.size();
  for (size_t i = 0; i < n; i++) {
    if (i) wt(' ');
    wt(val[i]);
  }
}

void print() { wt('\n'); }
template <class Head, class... Tail>
void print(Head &&head, Tail &&... tail) {
  wt(head);
  if (sizeof...(Tail)) wt(' ');
  print(forward<Tail>(tail)...);
}

// gcc expansion. called automaticall after main.
void __attribute__((destructor)) _d() { flush(); }
} // namespace fastio
using fastio::read;
using fastio::print;
using fastio::flush;

#define INT(...)   \
  int __VA_ARGS__; \
  read(__VA_ARGS__)
#define LL(...)   \
  ll __VA_ARGS__; \
  read(__VA_ARGS__)
#define U32(...)   \
  u32 __VA_ARGS__; \
  read(__VA_ARGS__)
#define U64(...)   \
  u64 __VA_ARGS__; \
  read(__VA_ARGS__)
#define STR(...)      \
  string __VA_ARGS__; \
  read(__VA_ARGS__)
#define CHAR(...)   \
  char __VA_ARGS__; \
  read(__VA_ARGS__)
#define DBL(...)      \
  double __VA_ARGS__; \
  read(__VA_ARGS__)

#define VEC(type, name, size) \
  vector<type> name(size);    \
  read(name)
#define VV(type, name, h, w)                     \
  vector<vector<type>> name(h, vector<type>(w)); \
  read(name)

void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void no(bool t = 1) { yes(!t); }
#line 3 "main.cpp"

using Re = double;
const Re INF = 4'000'000'000'000'000'000;

// a_i-sqrt(b_i-x)
template <typename T, bool COMPRESS, bool MINIMIZE>
struct LiChao_Tree_1 {
  using FUNC = pair<T, T>;
  vc<FUNC> funcs;

  static inline T evaluate(FUNC& f, ll x) {
    auto [a, b] = f;
    if (x > b) return INF;
    return a - sqrt(b - x);
  }

  vc<ll> X;
  ll lo, hi;
  vc<int> FID;
  int n, log, size;

  inline int get_idx(ll x) {
    if constexpr (COMPRESS) { return LB(X, x); }
    assert(lo <= x && x <= hi);
    return x - lo;
  }

  template <typename XY>
  LiChao_Tree_1(const vc<XY>& pts) {
    static_assert(COMPRESS);
    for (auto&& x: pts) X.eb(x);
    UNIQUE(X);
    n = len(X), log = 1;
    while ((1 << log) < n) ++log;
    size = 1 << log;
    FID.assign(size << 1, -1);
  }

  LiChao_Tree_1(ll lo, ll hi) : lo(lo), hi(hi) {
    static_assert(!COMPRESS);
    n = hi - lo, log = 1;
    while ((1 << log) < n) ++log;
    size = 1 << log;
    FID.assign(size << 1, -1);
  }

  void add_line(FUNC f) {
    int fid = len(funcs);
    funcs.eb(f);
    return add_line_at(1, fid);
  }
  void add_segment(ll xl, ll xr, FUNC f) {
    int fid = len(funcs);
    funcs.eb(f);
    xl = get_idx(xl), xr = get_idx(xr);
    xl += size, xr += size;
    while (xl < xr) {
      if (xl & 1) add_line_at(xl++, fid);
      if (xr & 1) add_line_at(--xr, fid);
      xl >>= 1, xr >>= 1;
    }
  }

  // [fx, fid]
  pair<T, int> query(ll x) {
    x = get_idx(x);
    int i = x + size;
    pair<T, int> res;
    if (!MINIMIZE) res = {-INF, -1};
    if (MINIMIZE) res = {INF, -1};
    while (i) {
      if (FID[i] != -1 && FID[i] != res.se) {
        pair<T, int> res1 = {evaluate_inner(FID[i], x), FID[i]};
        res = (MINIMIZE ? min(res, res1) : max(res, res1));
      }
      i >>= 1;
    }
    return res;
  }

  void add_line_at(int i, int fid) {
    int upper_bit = 31 - __builtin_clz(i);
    int l = (size >> upper_bit) * (i - (1 << upper_bit));
    int r = l + (size >> upper_bit);
    while (l < r) {
      int gid = FID[i];
      T fl = evaluate_inner(fid, l), fr = evaluate_inner(fid, r - 1);
      T gl = evaluate_inner(gid, l), gr = evaluate_inner(gid, r - 1);
      bool bl = (MINIMIZE ? fl < gl : fl > gl);
      bool br = (MINIMIZE ? fr < gr : fr > gr);
      if (bl && br) {
        FID[i] = fid;
        return;
      }
      if (!bl && !br) return;
      int m = (l + r) / 2;
      T fm = evaluate_inner(fid, m), gm = evaluate_inner(gid, m);
      bool bm = (MINIMIZE ? fm < gm : fm > gm);
      if (bm) {
        FID[i] = fid;
        fid = gid;
        if (!bl) { i = 2 * i + 0, r = m; }
        if (bl) { i = 2 * i + 1, l = m; }
      }
      if (!bm) {
        if (bl) { i = 2 * i + 0, r = m; }
        if (!bl) { i = 2 * i + 1, l = m; }
      }
    }
  }

private:
  T evaluate_inner(int fid, ll x) {
    if (fid == -1) return (MINIMIZE ? INF : -INF);
    return evaluate(funcs[fid], (COMPRESS ? X[min<int>(x, n - 1)] : x + lo));
  }
};

// a_i+sqrt(x-b_i)
template <typename T, bool COMPRESS, bool MINIMIZE>
struct LiChao_Tree_2 {
  using FUNC = pair<T, T>;
  vc<FUNC> funcs;

  static inline T evaluate(FUNC& f, ll x) {
    auto [a, b] = f;
    assert(x >= b);
    return a + sqrt(x - b);
  }

  vc<ll> X;
  ll lo, hi;
  vc<int> FID;
  int n, log, size;

  inline int get_idx(ll x) {
    if constexpr (COMPRESS) { return LB(X, x); }
    assert(lo <= x && x <= hi);
    return x - lo;
  }

  template <typename XY>
  LiChao_Tree_2(const vc<XY>& pts) {
    static_assert(COMPRESS);
    for (auto&& x: pts) X.eb(x);
    UNIQUE(X);
    n = len(X), log = 1;
    while ((1 << log) < n) ++log;
    size = 1 << log;
    FID.assign(size << 1, -1);
  }

  LiChao_Tree_2(ll lo, ll hi) : lo(lo), hi(hi) {
    static_assert(!COMPRESS);
    n = hi - lo, log = 1;
    while ((1 << log) < n) ++log;
    size = 1 << log;
    FID.assign(size << 1, -1);
  }

  void add_line(FUNC f) {
    int fid = len(funcs);
    funcs.eb(f);
    return add_line_at(1, fid);
  }
  void add_segment(ll xl, ll xr, FUNC f) {
    int fid = len(funcs);
    funcs.eb(f);
    xl = get_idx(xl), xr = get_idx(xr);
    xl += size, xr += size;
    while (xl < xr) {
      if (xl & 1) add_line_at(xl++, fid);
      if (xr & 1) add_line_at(--xr, fid);
      xl >>= 1, xr >>= 1;
    }
  }

  // [fx, fid]
  pair<T, int> query(ll x) {
    x = get_idx(x);
    int i = x + size;
    pair<T, int> res;
    if (!MINIMIZE) res = {-INF, -1};
    if (MINIMIZE) res = {INF, -1};
    while (i) {
      if (FID[i] != -1 && FID[i] != res.se) {
        pair<T, int> res1 = {evaluate_inner(FID[i], x), FID[i]};
        res = (MINIMIZE ? min(res, res1) : max(res, res1));
      }
      i >>= 1;
    }
    return res;
  }

  void add_line_at(int i, int fid) {
    int upper_bit = 31 - __builtin_clz(i);
    int l = (size >> upper_bit) * (i - (1 << upper_bit));
    int r = l + (size >> upper_bit);
    while (l < r) {
      int gid = FID[i];
      T fl = evaluate_inner(fid, l), fr = evaluate_inner(fid, r - 1);
      T gl = evaluate_inner(gid, l), gr = evaluate_inner(gid, r - 1);
      bool bl = (MINIMIZE ? fl < gl : fl > gl);
      bool br = (MINIMIZE ? fr < gr : fr > gr);
      if (bl && br) {
        FID[i] = fid;
        return;
      }
      if (!bl && !br) return;
      int m = (l + r) / 2;
      T fm = evaluate_inner(fid, m), gm = evaluate_inner(gid, m);
      bool bm = (MINIMIZE ? fm < gm : fm > gm);
      if (bm) {
        FID[i] = fid;
        fid = gid;
        if (!bl) { i = 2 * i + 0, r = m; }
        if (bl) { i = 2 * i + 1, l = m; }
      }
      if (!bm) {
        if (bl) { i = 2 * i + 0, r = m; }
        if (!bl) { i = 2 * i + 1, l = m; }
      }
    }
  }

private:
  T evaluate_inner(int fid, ll x) {
    if (fid == -1) return (MINIMIZE ? INF : -INF);
    return evaluate(funcs[fid], (COMPRESS ? X[min<int>(x, n - 1)] : x + lo));
  }
};

void solve() {
  LL(N);
  vi H(N), U(N), V(N);

  FOR(i, N) read(H[i], V[i], U[i]);

  /*
  auto f = [&](int i, int j) -> Re {
    ll d = H[j] - H[i];
    ll u = U[i], v = V[j];
    if (u * u < 2 * d) return INF;
    if (u * u + 2 * H[i] <= v * v + 2 * H[j]) {
      return (2 * d) / (u + sqrtl(u * u - 2 * d));
      // return u - sqrtl(u * u - 2 * d);
    }
    // return sqrtl(v * v + 2 * d) - v;
    return (2 * d) / (v + sqrtl(v * v + 2 * d));
  };

  vc<Re> dp(N, INF);
  dp[0] = 0;
  FOR(j, N) FOR(i, j) { chmin(dp[j], dp[i] + f(i, j)); }
  Re ANS = dp[N - 1];
  if (ANS == INF) return print(-1);
  print(ANS);
  */

  vi VH(N), UH(N);
  FOR(i, N) VH[i] = V[i] * V[i] + 2 * H[i];
  FOR(i, N) UH[i] = U[i] * U[i] + 2 * H[i];

  vc<Re> dp(N, INF);
  dp[0] = 0;
  LiChao_Tree_2<Re, true, true> LCT2(VH);

  auto dfs = [&](auto& dfs, int L, int R) -> void {
    if (R == L + 1) {
      // 計算
      if (L > 0) { chmin(dp[L], LCT2.query(VH[L]).fi - V[L]); };
      // LCT2 に線分として追加
      // a+sqrt(x-b)
      LCT2.add_segment(2 * H[L], UH[L], {dp[L], 2 * H[L]});
      return;
    }
    int M = (L + R) / 2;
    dfs(dfs, L, M);
    // [L,M) to [M,R)
    // evaluate する点は 2h[j]
    vi point;
    FOR(j, M, R) point.eb(2 * H[j]);
    LiChao_Tree_1<Re, true, true> LCT1(point);

    // 必要なら高速化可能
    vc<int> I, J;
    FOR(i, L, M) I.eb(i);
    FOR(j, M, R) J.eb(j);
    sort(all(I), [&](auto& a, auto& b) -> bool { return UH[a] > UH[b]; });
    sort(all(J), [&](auto& a, auto& b) -> bool { return VH[a] < VH[b]; });

    // VH[j] が小さな j から順に計算を行う
    for (auto& j: J) {
      // UH[i] <= VH[j] となる i からの遷移を追加
      while (len(I) && UH[I.back()] <= VH[j]) {
        // LCT1: a-sqrt(b-x)
        // dp[i] + U[i] - sqrt(UH[i]-2*H[j])
        int i = POP(I);
        LCT1.add_line({dp[i] + U[i], UH[i]});
      }
      // dp[j] を計算
      chmin(dp[j], LCT1.query(2 * H[j]).fi);
    }
    dfs(dfs, M, R);
  };
  dfs(dfs, 0, N);

  Re ANS = dp[N - 1];
  if (ANS == INF) { return print(-1); }
  print(ANS);
}

signed main() {
  solve();
  return 0;
}

详细

Test #1:

score: 100
Accepted
time: 1ms
memory: 3812kb

input:

5
2 1 7
14 6 4
18 1 7
21 2 5
28 4 10

output:

6.000000000000000

result:

ok found '6.0000000', expected '6.0000000', error '0.0000000'

Test #2:

score: 0
Accepted
time: 0ms
memory: 3544kb

input:

2
1 1 4
10 5 1

output:

-1

result:

ok found '-1.0000000', expected '-1.0000000', error '-0.0000000'

Test #3:

score: 0
Accepted
time: 0ms
memory: 3844kb

input:

10
16 1 6
27 8 8
32 4 8
51 6 6
62 5 10
81 5 9
84 10 6
92 1 2
94 9 6
96 7 9

output:

12.859830976959739

result:

ok found '12.8598310', expected '12.8598310', error '0.0000000'

Test #4:

score: 0
Accepted
time: 1ms
memory: 3576kb

input:

100
96 20 27
119 4 12
270 5 24
594 3 10
614 8 19
688 7 5
798 14 36
983 2 27
1057 20 21
1266 6 30
1388 18 18
1520 2 12
1809 4 26
1960 17 40
2137 8 10
2274 3 30
2320 14 34
2357 6 2
2392 12 5
2518 14 2
2681 10 29
2701 9 15
2865 3 38
3008 9 17
3021 6 39
3194 9 24
3212 14 12
3233 19 3
3628 18 6
3772 1 37...

output:

-1

result:

ok found '-1.0000000', expected '-1.0000000', error '-0.0000000'

Test #5:

score: 0
Accepted
time: 1ms
memory: 3728kb

input:

1000
370 20 90
1387 5 16
2315 1 25
3657 24 78
4597 11 42
5558 11 95
6044 12 80
6577 15 40
7746 12 87
7978 22 63
9306 23 72
9957 9 51
10182 27 36
10895 12 51
12595 28 58
12924 5 4
13166 11 36
15206 9 66
15938 18 70
17654 4 71
19189 2 6
19903 22 77
20032 30 57
20493 3 51
23719 3 65
24490 17 31
25831 2...

output:

-1

result:

ok found '-1.0000000', expected '-1.0000000', error '-0.0000000'

Test #6:

score: -100
Wrong Answer
time: 10ms
memory: 4792kb

input:

10000
8007 22 578
11024 369 551
19219 226 631
49583 226 629
72385 86 271
77173 257 574
78655 25 16
83483 301 820
100132 101 466
104988 267 221
105671 361 245
116034 132 421
127581 152 516
134693 356 423
137403 344 24
145224 29 785
177093 52 151
177351 98 252
187858 59 361
198082 220 525
200929 190 4...

output:

181590.721682319126558

result:

wrong answer 1st numbers differ - expected: '181483.4253835', found: '181590.7216823', error = '0.0005912'