Baltic OI 2012 - Mobile

Authors: Andi Qu, Ryan Chou

Official Analysis

If we can cover the highway using circles of radius r1r_1, then we can also cover the highway using circles of radius r2>r1r_2 > r_1. This suggests that we should binary search for the answer.

Checking a Radius

If a circle covers a part of a highway, it covers a line segment. Using the Pythagorean theorem (a2+b2=c2a^2 + b^2 = c^2), we can find the coordinates of the endpoints of each such segment. Let the segment from the ii-th tower be sis_i.

Checking whether a radius is good now becomes checking whether the union of these segments is a single segment that completely covers the highway.

We can solve this in O(NlogN)\mathcal{O}(N \log N) time by sorting the segments by their left endpoints and then merging each segment into the union if it intersects the union of the previous segments.

Unfortunately, this is just a bit too slow (O(NlogNlogL)\mathcal{O}(N \log N \log L) in total) and only scores 50 points.

Luckily, we don't have to sort the segments!

A Nice Property

Why would we need to sort the segments in the first place?

Imagine we had three segments ff, gg, and hh in that order in the unsorted list. Watch what happens when these segments are arranged as shown below:

Hack

Without sorting, gg wouldn't be part of the union since fg=f \cap g = \emptyset. However, the actual union contains all three segments.

But what if hh completely covers gg?

Antihack

In this case, it doesn't matter that gg isn't a part of the union, since fgh=fhf \cup g \cup h = f \cup h anyway.

The nice thing about this particular problem is that if we have segment sis_i coming after segment sjs_j in the list but sis_i's left endpoint is to the left of sjs_j's left endpoint, then sis_i must completely cover sjs_j.

Why is this true? The only time we will have segment sis_i coming after segment sjs_j in the list but sis_i's left endpoint is to the left of sjs_j's left endpoint is when xi>xjx_i > x_j and yi<yjy_i < y_j.

Circles

Clearly, sis_i completely covers sjs_j. We can therefore apply our algorithm for a sorted list and still get the correct answer!

This gets rid of the logN\log N factor in our original complexity and so the final complexity is O(NlogL)\mathcal{O}(N \log L), which is good enough for 100 points.

Implementation

#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
pair<long long, long long> p[1000000];
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);

Faster Solution

Although not necessary for full credit, there also exists an O(N)\mathcal{O}(N) solution.

Try to come up with it yourself before moving on!

Faster Solution

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!