Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Author: d
For the first subtask, it suffices to follow the definition of a good triplet. Firstly, there are
ways
to select
. Secondly, consider the condition that the origin is strictly inside the triangle. This is
equivalent to saying that
,
, and
divide the circle into
arcs, and each arc is strictly shorter than
.
This leads to the following approach. Sort the positions so that
, then check that
,
, and
.For example, the first of these checks can be implemented in code as P[b]-P[a] < (C+1)/2
in C++ or
Java, or P[b]-P[a] < (C+1)//2
in Python 3.
For the second subtask, the goal is to find a solution that works well when
is small. Let
be the
number of points drawn at location
. If three locations
satisfy the second condition, we want to add
to the answer. This approach is
and is too slow. However, we can improve from
three nested loops to two nested loops. If
and
are chosen already, either
does not exist, or
is in an
interval. It is possible to replace the third loop with a prefix sum array. This algorithm's time complexity is
.
It is possible to optimize this approach to
and earn
marks. The idea is to eliminate both the
and
loop. Start at
and compute
in
time. The next step is to transition from
to
, and to maintain
in
time. This requires strong familiarity with prefix sum arrays. Care
with overflow and off-by-one errors is required.
Comments
I found this problem a lot easier to think about if you count triplets of points that don't form a triangle and subtract that from the total number of triplets. These are exactly the triplets whose points all belong on a closed half of the circle, so sweeping two pointers along the circle suffices to do this in
time.