Quantcast
Channel: CodeChef Discuss - latest questions
Viewing all articles
Browse latest Browse all 39796

DARTSEGM - Editorial

$
0
0

PROBLEM LINK:

Div1
Div2
Practice

Setter-Ildar Gainullin
Tester-Hasan Jaddouh
Editorialist-Abhishek Pandey

DIFFICULTY:

HARD

PRE-REQUISITES:

Segment Tree, Convex Hull, Computation Geometry (i.e. the proof mentioned here)

PROBLEM:

$N$ darts are thrown randomly on a ${10}^{9} \times {10}^{9}$ board. We need to answer $Q$ queries where each query asks for the distance between farthest darts where we have to consider only darts thrown in throws $[l,r].$

QUICK EXPLANATION:

Winning Point- The one who could deduce the statement proved by proof given in pre-requisites can easily do this question like a cakewalk.

Go through the proof in the pre-requisites. It says that, for $N$ randomly generated points in $2-D$ plane, the expected size of their convex hull is of order $O(LogN)$. (In other words, all the $N$ points will be "enclosed" or "covered" by $\approx LogN$ points.)

It then becomes quite easy. We make a segment tree, where each node stores the convex hull of darts thrown in range $[l,r]$. The farthest points must be part of the hull (Why?). The expected size of hull is $O(LogN)$, hence brute-force iteration over points can answer the queries in $O({Log}^{2}N)$.

EXPLANATION:

The explanation of this question is surprisingly straightforward. I will assume you guys went through the requested links in the pre-requisites. If not, go back and make sure you grasp the concept, especially the definition of convex hull and the concept of segment trees (along with the proof, of course!).

Despite a straight-forward explanation, the editorial will have 3 parts, each of them highlighting/discussing one of the three key concepts to solve this question. We will be using setter's solution primarily, for any doubts in implementation.

1. Randomness of Points-

There is a good reason why the setter bothered to mention in black and white that points are randomly generated. This allows us to use the observation of above proof. The convex hull of $N$ randomly generated points will be of (expected) size $LogN$.

In other words, we can quote it as "Expected number of points on convex hull when points are generated randomly from square $K⋅K$ is $O(logK)$."

"That is fine Mr. So-So-Editorialist. But whats the use of this?"

The use is, that, the farthest points must be a part of the hull (Why?) (Answer given in my corner :D). Hence, we don't need to keep account of all the points, but only a selected few which make the hull. If this doesnt strike a bell, look in explanation in below tab.

View Content

"Ya-Ya, thats fine Mr So-So Editorialist. But what about the worst case?"

Yes, I know this is a question among minds of $>80\%$ newbies. To answer this, yes, the solution will fail at the worst case, which happens if all the $N$ points are part of the hull. But again, we must make one thing clear, the points are randomly generated. Hence, the chances of this worst case happening are $<{10}^{-9}$ (Actually even lesser!). So, we can find the expected number of test cases having worst case as $0$ (XD). Jokes aside, the real significance is same, that the probability of the worst case happening is way too less, its lesser than probability of us getting hit by a meteorite. We dont often get hit by meteorites, do we? Getting hit by worst case is even more rare! :D

In crux, probabilistic approach is followed here, which rules out worst case happening with a considerable amount of confidence and accuracy.

As a homework, can you at least theoretically explore why the chances of worst case are so less?

2. Building Segment Tree-

The first thing to note in any segment tree problem is, what to store in the nodes. We will be storing the convex hull of points lying in range $[l,r]$ in the respective node. (As usual, tabs if this explanation seems insufficient to you.)

View Content

The implementation is also quite easy. Here is the commented code to aid in implementation-

void build(int v, int l, int r)
{
    if (r - l == 1)//Only 1 point. 
    {
        t[v] = {a[l]};
    }
    else
    {
        int m = (l + r) / 2;
        build(v * 2 + 1, l, m);//Storing of points in range [l,m]
        build(v * 2 + 2, m, r);//Storing of points in range [m,r]
        t[v] = mrg(t[v * 2 + 1], t[v * 2 + 2]);//Merging above two to get points in range [l,r]
        t[v] = hull(t[v]);//Making hull of these points via standard algorithm
    }
}

3. Answering the Queries-

Answering the queries is also, quite simple. I will again stress that, the points with farthest distance must lie of the hull. We have stored the hull of points in range $[l,r]$ in nodes, its time to retrieve them for answer :). Refer to code below-

vector <pt> get(int v, int l, int r, int tl, int tr)//Return a vector (dynamic array) consisting of
//points in hull
{
    if (tl >= r || tr <= l)//Out of range. Return nothing.
    {
        return {};
    }
    if (tl >= l && tr <= r)//Completely within range. Return the stored hull.
    {
        return t[v];
    }
    else
    {
        int tm = (tl + tr) / 2;
//Query for range [l,m] and [m,r] and return the answer obtained after merging them
        return mrg(get(v * 2 + 1, l, r, tl, tm), get(v * 2 + 2, l, r, tm, tr));
    }
}

The above is nothing but a typical segment tree query function. If any part of above (like out-of-range, completely in range etc.) isnt clear, do first check up segment trees in more detail. Else, drop a comment here :)

Now, all thats left is to iterate over the points. Since we have $\approx LogN$ points, we can easily do a brute force to answer query in $O({Log}^{2}N)$. Refer to pseudo code below-

for (int i = 0; i < (int) b.size(); i++)//b stores the hull
        {
            for (int j = i + 1; j < (int) b.size(); j++)
            {
                ans = max(ans, abs(b[i] - b[j]));
//Iterate over all pairs of points. Only Log^2 N pairs are possible. Store the maximum distance obtained.
            }
        }

SOLUTION:

For your quick reference, the required codes are pasted in tabs. This is, so that you can refer to code without having to wait for @admin to link them. Editorialist's solution will be put on demand.

Setter

View Content

Tester

View Content

$Time \space Complexity= O( (N+Q)*{Log}^{2}N)$

CHEF VIJJU'S CORNER :D

1. Why the farthest points must lie on hull.

View Content

2. Look at the proof given by me in Point 1. Evaluate it in terms of correctness and soundedness, and hence prove the same in given scenario, "$A$ is an internal point, $B$ is part of hull. Prove that $A$ must be part of hull as well for maximum distance."

3. Refer to code for answering the queries. Then, look at the diagram in the tab below, and answer how does the query function merges them. Try to answer by giving an image for clearer answer, along with your reasoning for the same. Analyze the case for any possible issues with time complexity, if they can exist. If not, argue why not.

View Content

4. Setter's Notes-

View Content

5. Tester's Notes-

View Content

6. Why does the worst case occur so rarely? Can you give at least intuitions for it? Some grounds of arguments are, "Number of specific arrangements in numerator v/s ALL possible arrangements of all $N$ points in denominator" or arguments on "Distance between $X$ randomly generated points being at least $K$" &etc.


Viewing all articles
Browse latest Browse all 39796

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>