Official

D - Destroyer Takahashi Editorial by en_translator


In this problem, actually it is optimal to choose the position to punch by the following algorithm.

  • First, sort the segments \([L, R]\) that the walls exist.
  • Next, look up the walls in the sorted order, and if the walls is not destroyed yet, punch the leftmost position to destroy it.

The following is a formal definition of the procedures to destroy. First, let \(x\) be the final coordinate that was punched. (If no punch has been done yet, \(x = -\infty\).) Here, since we sorted the walls in the increasing order of the leftmost coordinate, as the procedures go on, \(x\) gradually increases (it monotonically increases).

For an inspection of a wall of the sorted sequences, lets divide into cases by whether R \(L\) is greater than \(x + D - 1\) or not. (corrected at 12-06 10:30)

  • If \(L\) is greater than \((x + D - 1)\), by the monotonicity of \(x\), this wall is obviously never destroyed. In that case, let \(x = R\) and punch \([R, R + D - 1]\).
  • If \(L\) is less than or equal to \((x + D - 1)\), we do nothing because the wall have been destroyed by the last punch.

We will prove the justice of the algorithm. Let \(A\) be the answer obtained by the algorithm above. If we can prove that “the answer is less than or equal to \(A\)” and “the answer is greater than or equal to \(A\)”, then it is proved that the answer for this problem is exactly \(A\).
The two proof can be done as follows.

  • (The proof that the answer is less than or equal to \(A\)): Since all the walls have been destroyed by the procedure so far, we know that there is a way to destroy the walls in \(A\) number of punches. Therefore, the answer is less than or equal to \(A\).
  • (The proof that the answer is greater than or equal to \(A\)): From the \(N\) walls, choose the walls for which in the conditional branch above it was determined that “\(R\) was greater than \(x + D - 1\).” No matter which two walls we choose from these \(A\) number of walls, these walls are distant by at least \(D\), so these walls cannot be destroyed at once. Therefore, there are at least \(A\) walls that cannot be destroyed at once, so Takahashi has to punch at least \(A\) times. Therefore, the answer is greater than or eqaul to \(A\).

Therefore, the algorithm has been justified.
The time complexity is \(\mathrm{O}(N \log N)\), where the bottleneck is sorting the sequence.

By the way, the algorithm used for this problem is same as that for the famous problem called “segment scheduling problem.”

The following is a sample code in C++.

#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>
using namespace std;

int main() {
  using ll = long long;
  using P = pair<ll, ll>;
  ll N, D, L, R;
  vector<P> LR;
  cin >> N >> D;
  for (int i = 0; i < N; i++) {
    cin >> L >> R;
    LR.emplace_back(L, R);
  }
  sort(begin(LR), end(LR), [](P& a, P& b) { return a.second < b.second; });
  ll ans = 0, x = -(1LL << 40);
  for (auto& [l, r] : LR) {
    if (x + D - 1 < l) ans++, x = r;
  }
  cout << ans << "\n";
}

posted:
last update: