Official

C - Collision 2 Editorial by en_translator


First, if you are new to competitive programming, you may try to simulate the movements by naively moving people in the left and right. However, in this problem, we need to simulate enormous number of people in a vast space, as \(N \leq 2\times 10^5, x,y \leq 10^9\), so we don’t have enough computational resources for the naive simulation.
In such case, we need to construct an efficient algorithm based on appropriate observations. In order to do so, it is important to formulate “in what condition will the condition happen?” Without the formulation, we cannot construct proper algorithms.

Now, let’s find the necessary and sufficient condition of the occurrence of collision. By considering properly, we can see that Person \(p\) and Person \(q\) collides if and only if:

  • the \(y\) coordinate of Person \(p\) and Person \(q\) are the same;
  • if the \(x\) coordinate of Person \(p\) is smaller than that of Person \(p\), then Person \(p\) is facing left and Person \(q\) is facing right (and vice versa).

By rephrasing like this, this problem is boiled down to a problem of “is there a pair of people \((p, q)\) that satisfies the condition above?” Thus, we can solve this problem by iterating through all \((p, q)\)… wait, it costs \(\mathrm{O}(N^2)\), leading to TLE (Time Limit Exceeded).

Let’s deepen the observation. For a set of people with the same \(y\) coordinate, let’s consider “in what condition does a collision occurs?” Then we can see that a collision occurs if and only if the following two people collides:

  • the leftmost person facing right, and
  • the rightmost person facing left.

In other words, among the people with the same \(y\) coordinate, all the people except for the two mentioned above is unimportant.

Therefore, we can determine fast if a collision happens by holding the following two associative arrays with elements of (key, value). (For more details, please refer to the sample code.)

  • right_min, the person facing right whose \(y=k\) and \(x\) coordinate is the smallest, where \(k\) denotes the key
  • left_max, the person facing left whose \(y=k\) and \(x\) coordinate is the smallest, where \(k\) denotes the key

The time complexity is \(\mathrm{O}(N)\) or \(\mathrm{O}(N \log N)\). Here is a sample code in Python.

def Yes():
  print("Yes")
  exit(0)


N = int(input())
X, Y = [], []
for _ in range(N):
  x, y = map(int, input().split())
  X.append(x)
  Y.append(y)
S = input()

right_min, left_max = dict(), dict()

for i in range(N):
  if S[i] == 'R':
    if Y[i] in left_max and X[i] < left_max[Y[i]]:
      Yes()
  else:
    if Y[i] in right_min and right_min[Y[i]] < X[i]:
      Yes()

  if S[i] == 'R':
    if Y[i] in right_min:
      right_min[Y[i]] = min(X[i], right_min[Y[i]])
    else:
      right_min[Y[i]] = X[i]
  else:
    if Y[i] in left_max:
      left_max[Y[i]] = max(X[i], left_max[Y[i]])
    else:
      left_max[Y[i]] = X[i]

print("No")

posted:
last update: