SRM 734, D1, 300-Pointer (TheRoundCityDiv1)

James S. Plank

Tue Aug 21 17:57:10 EDT 2018

You have to be on your game for this one. Unlike the Div2 version of this problem, where you can simply iterate over all of the potential home points, this one requires some constructive thought. In particular, you can't get too much worse than a linear algorithm on r. Maybe (r log(r)).

Let's think about it incrementally. First, there will be two homes visible on the x-axis (-1,0) and (1,0) and two homes visible on the y-axis (0,-1) and (0,1). Then, if you count the homes in the quadrant where x > 0 and y > 0, you can multiply that answer by four, add it to the four homes along the axes, and that's your answer.

So, your goal is to count the homes where x > 0 and y > 0.

Let's continue thinking incrementally -- lets loop from y = 1 to y = r-1. For each value of y, can we can determine the number of homes at points (x,y) that are visible? It's not too hard to compute the maximum value of x such that (x,y) is inside the circle. Let's call that point xmax. Can we calculate the number of visible homes using just the values y and xmax? Let's try some examples:

Let's think about it more precisely. If a home at (x,y) is invisible, then there must be a point at (x/f, y/f) for some integer f. So, for a home to be invisible, x and y cannot be relatively prime. OK -- that lets us state the problem in a different way -- given y and xmax, how many numbers from 1 to xmax are relatively prime with y? As you can see from the examples above, when y is a prime number, you can simply divide xmax by y and subtract that from xmax. If y is a power of a prime number, then you divide xmax by the prime number, and subtract it from xmax. What if y is the product of more than one prime number?

Again, look at an example. Suppose y is 6. Then, if we subtract xmax by both xmax/2 and xmax/3, then we've subtracted too many numbers -- we have subtracted the multiples of 6 twice. To fix this, we need to add back in the xmax/6 multiples of six.

The general principle going on here is called the "Inclusion-exclusion" principle. It has its own Wikipedia page. Suppose y has m unique prime factors. Then, the count of numbers between one and xmax that are relatively prime with y are:

So now we have a strategy: Let's do an example. When r is 47, and y is 12. We know that x2 + 122 ≤ 472, so xmax = 45. Now, we want to calculate how many x's there are from 1 to 45 which are relatively prime with 12. So, we find the unique prime factors of 12: 2 and 3. And then we enumerate every combination pf of the unique prime factors: Thus, the total number of visible houses where y is 12 is 15. In case you are wondering, those are when x is one of { 1, 5, 7, 11, 13, 17, 19, 23, 25, 29, 31, 35, 37, 41, 43 }.

Running Time

Well, I started by generating all of the prime numbers up to sqrt(r) and storing them in a vector primes. That's less than O(r) (There are 168 primes ≤ 1,000). The main loop is O(r), and with each element, you need to determine the unique prime factors. That's O(primes.size()). Then the loop to enumerate all combinations of unique prime factors is 2(# of unique prime factors). 2*3*5*7*11*13*17 = 510510, so the number of unique prime factors will be pretty small. I had a feeling that this one would run up against Topcoder's limits when r was 1,000,000. On my Mac, it was over 2 seconds unoptimized, but it passed the system test, so it must have gotten under when optimized!