Submission #515026

#TimeUsernameProblemLanguageResultExecution timeMemory
515026CrouchingDragonSafety (NOI18_safety)C++17
100 / 100
87 ms7480 KiB
#include <bits/stdc++.h>

template <typename T>
using minpq = std::priority_queue<T, std::vector<T>, std::greater<T>>;

template <typename T>
struct SlopeTrick {
  inline static const T inf = std::numeric_limits<int64_t>::max() / 2;
  T cost = 0, left_offset = 0, right_offset = 0;
  std::priority_queue<std::pair<T, T>> left;
  minpq<std::pair<T, T>> right;
  SlopeTrick() {
    left.emplace(-inf, 0);
    right.emplace(+inf, 0);
  }
  void rebalance() {
    while (true) {
      auto [xl, sl] = left.top();
      xl -= left_offset;
      auto [xr, sr] = right.top();
      xr += right_offset;
      if (xl <= xr) break;
      left.pop();
      right.pop();
      T take = std::min(sl, sr);
      cost += take * (xl - xr);
      sl -= take;
      sr -= take;
      left.emplace(xr + left_offset, take);
      right.emplace(xl - right_offset, take);
      if (sl) {
        left.emplace(xl + left_offset, sl);
      }
      if (sr) {
        right.emplace(xr - right_offset, sr);
      }
    }
  }
  // adds f(x) = s * max(a - x, 0)
  void add_left(T a, T s) {
    left.emplace(a + left_offset, s);
    rebalance();
  }
  // adds f(x) = s * max(x - a, 0)
  void add_right(T a, T s) {
    right.emplace(a - right_offset, s);
    rebalance();
  }
  // adds f(x) = s * abs(x - a)
  void add_abs(T a, T s) {
    left.emplace(a + left_offset, s);
    right.emplace(a - right_offset, s);
    rebalance();
  }
  void relax_left(T offset) {
    left_offset += offset;
    rebalance();
  }
  void relax_right(T offset) {
    right_offset += offset;
    rebalance();
  }
  void relax(T offset) {
    left_offset += offset;
    right_offset += offset;
    rebalance();
  }
};

constexpr int64_t inf = std::numeric_limits<int64_t>::max() / 2;

int main() {
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(nullptr);
  int N, H;
  std::cin >> N >> H;
  std::vector<int> S(N);
  for (int i = 0; i < N; ++i) {
    std::cin >> S[i];
  }
  SlopeTrick<int64_t> st;
  for (int i = 0; i < N; ++i) {
    st.relax(H);
    st.add_abs(S[i], 1);
  }
  std::cout << st.cost << '\n';
  exit(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...