Official

F - Sum of Minimum Distance Editorial by evima


The answer does not change if we always ensure \(0 \leq x < A+B\) during the process, given \(1 \leq n < A+B\). This can be proved as follows. First, let’s aim to construct \(n = Au + Bv\). Since \(1 \leq n < A+B\), exactly one of \(u\) and \(v\) is positive and the other is non-positive. For example, if \(u > 0\) and \(v \leq 0\), the operations can be performed as follows:

  • Perform the following operation \(u\) times:
    • As long as \(x \geq B\), perform \(x \to x-B\).
    • Perform \(x \to x+A\).
  • Finally, for the remaining number of times, perform \(x \to x-B\).

The same process can be applied when \(u \leq 0\) and \(v > 0\).

We will call the case where \(u > 0\) the \(+A\) pattern, and the case where \(v > 0\) the \(+B\) pattern.

It is notable here that the procedure performed is constant regardless of the value of \(n\). Moreover, if you keep repeating the \(+A\) pattern operations, \(x\) will eventually return to \(0\). If you reverse the order of these operations, you will obtain the \(+B\) pattern. In other words, the movements of each pattern form a cycle with \(A+B\) vertices \(0, 1, \cdots, A+B-1\), and the only difference between the patterns is the order in which the cycle is traversed.

Ultimately, what we need to find is the “shortest path” to each vertex. In the end, for each pattern, we can determine the number of initial movements that correspond to the shortest path.

Now, the following problem needs to be solved (fast):

  • You are given integers \(A, B, X, Y, N, C\). Starting with integers \(x = 0, cur = 0, ans = 0\), repeat the following operation \(N\) times. Fnid the final value of \(ans\).
    • When \(x < B\):
      • If \(x < C\), do \(ans\operatorname{+=}cur\).
      • Do \(x\operatorname{+=}A\) and \(cur\operatorname{+=}X\).
    • When \(x \geq B\):
      • If \(x < C\), do \(ans\operatorname{+=}cur\).
      • Do \(x\operatorname{-=}B\) and \(cur\operatorname{+=}Y\).

In fact, the following generalized problem can be solved:

  • You are given integers \(A, B, C, N\), and elements \(AX, AY, BX, BY\) of some monoid \(M\). Starting with integer \(x = 0\) and elements \(cur = id, ans = id\) of \(M\), repeat the following operation \(N\) times. Find the final value of \(ans\).
    • When \(x < B\):
      • If \(x < C\), set \(ans\operatorname{:=}AX \cdot ans\); if \(x \geq C\), set \(ans\operatorname{:=}AY \cdot ans\).
      • Do \(x\operatorname{+=}A\).
    • When \(x \geq B\):
      • If \(x < C\), set \(ans\operatorname{:=}BX \cdot ans\); if \(x \geq C\), set \(ans\operatorname{:=}BY \cdot ans\).
      • Do \(x\operatorname{-=}B\).

This can be solved using a similar approach to finding floor_sum (gauss_sum). For example, consider the case when \(A < B\). If we represent \(B = pA + q\) (\(q < A\)), we can combine \(p\) repetitions of \(+A\) and one \(-B\) into a single movement of \(-q\). The values of \(AX, AY, BX, BY, C\) also need to be adjusted accordingly, and this requires detailed case-by-case handling. The details are omitted here, so please refer to the sample code. The case \(A > B\) can be handled similarly.

With this approach, you can design a solution that works in \(O(\operatorname{poly} \log (A+B))\) time per case. The sample code works in \(O(\log^2 \max(A+B))\) per case.

Sample Code (C++)

posted:
last update: