ENG  RUSTimus Online Judge
Online Judge
Problems
Authors
Online contests
About Online Judge
Frequently asked questions
Site news
Webboard
Links
Problem set
Submit solution
Judge status
Guide
Register
Update your info
Authors ranklist
Current contest
Scheduled contests
Past contests
Rules
back to board

Discussion of Problem 1464. Light

Some review
Posted by Igor Parfenov 29 Jun 2026 23:18
The idea of problem is pretty interesting. But for me it was implementation hell.
Re: Some review
Posted by Solver 28 Jul 2026 11:13
Made it with almost 1st submit, so I'll describe my way of avoiding "implementation hell".

First of all obvious things: x[i] -= x0, y[i] -= y0, so origin is at zero. x[n]=x[0], y[n]=y[0] to reduce amount of 'if's.

Second, all that we love with precision maths. I.e.
a == b --- fabs(a-b)<eps
a > b --- a > b + eps
a >= b --- a > b - eps
eps=1e-8 is enough here, but I did it without trigonometry

The main idea is that every segment covers some range of angles [a1;a2], so we have a set of "control points" of the form "angle;seg-i-start", "angle;set-i-end". So when you have this set of control points, segments will not change their relative order between two consecutive control points which can be checked by intersecting a ray and checking square of distance.

Now on how to avoid trigonometry in these and other problems like convex hull - just store vectors (segment endpoints). When comparing them for an "angle", first check the side. Let side=0 be the [0;pi) range - that is 'dy>0 || dy==0 && dx>0', then side=1 goes for [pi;2pi) range. Then you just compare sides, and if side is the same, check the sign of cross product for comparison. You will also need a special record for 2pi (side=2), I coded it as dx=0,dy=0, but be careful to treat it as (1,0) when raycasting later.

Now, ignore segments which contain origin in negative subplane (or on zero, i.e. no control points for them). Then the only thing to be dealt with is crossing 2pi-0 boundary. Criteria here is 'y[i]<0 && y[i+1]==0' - then it starts at (x[i];y[i]) and ends at (0;0). Or 'y[i]<0 && y[i+1]>0' then it starts at (x[i];y[i]), ends at (0;0), then starts at (1;0) and ends at (x[i+1];y[i+1]). These are just for 'angular' sorting of control points.

After that you will have first control point at (1;0) (angle=0) and last control point at (0;0) (angle=2pi). The rest is just running through them. Pick all control points which are 'equal' on that angular criteria, and process them - i.e. add/del corresponding segments to the heap according to px[i];py[i] ray intersection length for that control point. Let the next control point which is 'greater' according to angular criteria be 'j', after that pick topmost (nearest) segment from the heap, get intersection with px[i];py[i] ray, and px[j];py[j] ray (here don't forget to treat 0;0 as 1;0). After that add their cross product to the answer.