QOJ.ac

QOJ

Type: Editorial

Status: Open

Posted by: Anonymous

Posted at: 2026-03-25 19:10:56

Last updated: 2026-03-25 19:16:00

Back to Problem

My Solution for Problem #17320

Here is a polished English editorial draft for the alternative solution based on the same circle/compression model as the official code, but with no binary search.


Editorial (Alternative Solution Without Binary Search)

Each boss attacks at times [ f_i,\ f_i+d,\ f_i+2d,\dots ] and Franklin may parry only at an exact attack time. After parrying at time (t), he cannot parry again until time (t+w). The goal is to defeat all bosses as early as possible. The input size is up to (3\cdot 10^5), so we need an (O(N\log N))-type solution.

1. From parries to intervals

If Franklin parries boss (i) at time (t), then during the entire interval [ [t,\ t+w) ] he is unavailable.

So instead of thinking about “choosing one attack time per boss”, we can think of “choosing one interval per boss”:

[ [f_i+kd,\ f_i+kd+w), \qquad k\ge 0. ]

Two bosses can both be defeated iff the chosen intervals do not overlap. Therefore, the problem becomes:

Choose one interval from each periodic family so that all chosen intervals are disjoint, and minimize the right endpoint of the last chosen interval.

If the minimum possible right endpoint is (R), then the answer to the original problem is (R-w).


2. Splitting off the full cycles

Let us look at a single boss modulo (d). Its interval starts at (f_i) and ends at ((f_i+w)\bmod d).

Write the clockwise arc length from (f_i) to ((f_i+w)\bmod d) as [ \mathrm{rem}_i. ] Then [ w-\mathrm{rem}_i ] is always a multiple of (d). This is exactly the “full-cycle” part of the interval length.

So we separate the total length (w) into:

  • a reduced circular arc of length (\mathrm{rem}_i < d),
  • plus a constant multiple of (d).

Summing this over all bosses gives a fixed additive term. Thus, we may first solve a reduced circular problem, and then add the constant back at the end.

This is the same invariant used by the official solution, but we will optimize the reduced problem differently.


3. Compressing the circle

We collect all important positions on the circle:

  • every starting point (f_i),
  • every ending point ((f_i+w)\bmod d),
  • and (0).

After sorting and deduplicating them, we obtain breakpoints [ q_1 < q_2 < \cdots < q_m, ] which partition the circle into elementary segments: [ [q_1,q_2),\ [q_2,q_3),\ \dots,\ [q_m,d)\cup[0,q_1). ]

Inside one elementary segment, the set of bosses whose reduced arcs cover that segment never changes.

For each segment (i), let [ cf[i] ] denote how many boss-arcs cover it.

This value can be computed by the usual difference-array sweep on the circle.


4. What does a candidate right endpoint need to satisfy?

Suppose we want the reduced schedule to finish by time (x).

For a fixed elementary segment whose endpoint is (E_i), the copies of that segment appear on the number line at times

[ E_i,\ E_i+d,\ E_i+2d,\dots ]

Hence, the number of copies of this segment available up to time (x) is

[ \left\lfloor \frac{x-E_i}{d} \right\rfloor + 1, ] which is the same quantity the official solution computes as [ \left\lfloor \frac{x}{d} \right\rfloor + [x\bmod d \ge E_i]. ]

To realize all boss intervals, segment (i) must be used exactly (cf[i]) times. Therefore, a necessary condition is

[ x \ge d,(cf[i]-1)+E_i. ]

Define the base requirement [ B_i = d,(cf[i]-1)+E_i. ]

So any feasible reduced finishing time must satisfy

[ x \ge \max_i B_i. ]


5. When does a segment give us “extra slack”?

If [ x \ge d\cdot cf[i] + E_i, ] then segment (i) has one extra copy beyond the (cf[i]) copies required by the boss intervals themselves.

Define the activation time [ A_i = d\cdot cf[i] + E_i. ]

Interpretation:

  • (x \ge B_i): segment (i) is just sufficient,
  • (x \ge A_i): segment (i) has one surplus copy.

That surplus copy is exactly what allows us to “bridge” between different connected components of interval pieces.

This is the key to removing binary search.


6. A graph view

Create a graph on the compressed breakpoints.

There are two kinds of edges:

1) Boss edges

For each boss, connect the breakpoint of (f_i) to the breakpoint of ((f_i+w)\bmod d).

These edges represent the boss intervals themselves. They are always present.

2) Circle edges

For each elementary segment (i), connect its two endpoints on the circle.

This edge becomes usable only when the segment has surplus capacity, i.e. only when [ x \ge A_i. ] So we assign this edge weight (A_i).


7. The feasibility criterion

Now contract all boss edges first. This produces several connected components.

For a fixed (x), the reduced problem is feasible iff:

  1. every segment has enough copies, i.e. [ x \ge \max_i B_i, ]
  2. after adding all circle edges with [ A_i \le x, ] all contracted components become connected.

This is exactly the same condition that the official binary-search check tests. The difference is that we will now compute the minimum such (x) directly.


8. Eliminating binary search with Kruskal

After contracting the boss edges, we obtain a graph whose vertices are the resulting components, and whose edges are the circle edges with weights (A_i).

We want the minimum (x) such that all components are connected using only edges of weight at most (x). That is precisely the minimum bottleneck connectivity value of this graph.

Equivalently:

  • sort all circle edges by (A_i),
  • run Kruskal,
  • let (\beta) be the weight of the last edge used to connect all components.

Then the minimum feasible reduced right endpoint is simply

[ X = \max\left(\max_i B_i,\ \beta\right). ]

So the original answer is

[ \boxed{X + \text{sum} - w} ]

where sum is the total full-cycle contribution accumulated from all bosses.

This gives an (O(N\log N)) algorithm with no parametric search.


9. Why this works

The official solution performs a binary search on (x) and repeatedly asks:

  • do all segments have enough copies up to (x)?
  • and do the surplus segments connect all boss-components?

Our solution observes that each circle edge has a precise activation time (A_i). So instead of repeatedly checking different values of (x), we can directly ask:

What is the smallest bottleneck value needed to connect all components?

That is exactly a Kruskal/MST bottleneck problem.

So the two solutions rely on the same structural invariant, but the optimization layer is different:

  • Official solution: binary search + DSU check
  • Alternative solution: one DSU contraction + one Kruskal pass

10. Complexity

Let (m) be the number of compressed breakpoints. Since each boss contributes at most two breakpoints, we have [ m = O(N). ]

The algorithm performs:

  • coordinate compression: (O(N\log N)),
  • a sweep to compute coverage counts: (O(N)),
  • one Kruskal run on (O(N)) edges: (O(N\log N)).

Therefore the total complexity is

[ \boxed{O(N\log N)} ]

with linear memory. This is fast enough for (N\le 3\cdot 10^5).


If you want, I can also turn this into a more contest-style editorial with the standard sections Idea / Construction / Correctness Proof / Complexity, ready to paste into a write-up.

Comments

No comments yet.
Comments are disabled for this thread.