Official

F - Cleaning Robot Editorial by leaf1415


便宜上、「文字列 \(S\)\(K\) 個連結したプログラムを実行する」ことを「文字列 \(S\)\(K\) 回繰り返し実行する」と解釈します。

文字列 \(S\)\(1\) 回目の実行時の、ロボットの位置の変化を \((0, 0) \rightarrow (x_1, y_1) \rightarrow (x_2, y_2) \rightarrow \cdots \rightarrow (x_{|S|}, y_{|S|})\) とします。ただし、\(|S|\) は文字列 \(S\) の長さです。
\(x_{|S|}, y_{|S|}\) をそれぞれ \(a, b\) とおきます。

\(1\) 回目の実行時にロボットが訪れるマス( \(1\) 回目実行開始前の位置 \((0, 0)\) も含む)の集合を \(V_1\) とおきます。 つまり、\(V_1\)\((0, 0), (x_1, y_1), (x_2, y_2), \cdots, (x_{|S|}, y_{|S|})\) から重複を除いて得られる集合です。 \(V_1\) の要素に適当に番号づけをし、

\(V_1 = \lbrace (X_1, Y_1), (X_2, Y_2), \ldots, (X_N, Y_N) \rbrace\)

と表します。ただし、\(N\)\(V_1\) の要素数です。
このとき、\(2\) 回目の実行時にロボットが訪れるマス( \(2\) 回目実行開始前の位置も含む)の集合 \(V_2\) は、\(V_1\) の各要素を \((a, b)\) だけ平行移動した、

\(V_2 = \lbrace (X_1 + a, Y_1 + b), (X_2 + a, Y_2 + b), \ldots, (X_N + a, Y_N + b) \rbrace\)

となります。
\(3\) 回目の実行時にロボットが訪れるマス( \(3\) 回目実行開始前の位置も含む)の集合 \(V_3\) は、\(V_2\) の各要素をさらに \((a, b)\) だけ平行移動した、

\(V_3 = \lbrace (X_1 + 2a, Y_1 + 2b), (X_2 + 2a, Y_2 + 2b), \ldots, (X_N + 2a, Y_N+ 2b) \rbrace\)

となります。
一般に、\(k\) 回目の実行時にロボットが訪れるマス( \(k\) 回目実行開始前の位置も含む)の集合 \(V_k\) は、

\(V_k = \lbrace (X_1 + (k-1)a, Y_1 + (k-1)b), (X_2 + (k-1)a, Y_2 + (k-1)b), \ldots, (X_N + (k-1)a, Y_N+ (k-1)b) \rbrace\)

となります。

特に、\(i = 1, 2, \ldots, N\) について \((X_i, Y_i) \in V_1\) は、

  • \(2\) 回目の実行では \((X_i + a, Y_i + b)\) に対応し、
  • \(3\) 回目の実行では \((X_i + 2a, Y_i + 2b)\) に対応し、
  • \(\cdots\)
  • \(k\) 回目の実行では \((X_i + (k-1)a, Y_i + (k-1)b)\) に対応する

ということに注意します。

ここで、\(i = 1, 2, \ldots, N\) に対して、

\(d_i\) := (\((X_i+ja, Y_i+jb) \in V_1\) を満たす最小の正整数 \(j\)

と定めます。ただし、そのような正整数 \(j\) が存在しないときは \(d_i := \infty\) とします。

このとき、ある一つの \((X_i, Y_i) \in V_1\) に注目すると、\(d_i\) 回目の実行までは、

  • マス \((X_i, Y_i)\) は、\(1\) 回目の実行時に初めて訪れるマスである。
  • マス \((X_i + a, Y_i + b)\) は、\(2\) 回目の実行時に初めて訪れるマスである。
  • マス \((X_i + 2a, Y_i + 2b)\) は、\(3\) 回目の実行時に初めて訪れるマスである。
  • \(\cdots\)
  • マス \((X_i + (d_i-1)a, Y_i + (d_i-1)b)\) は、\(d_i\) 回目の実行時に初めて訪れるマスである。

となりますが、\((d_i+1)\) 回目以降の実行では、

  • マス \((X_i + d_ia, Y_i + d_ib)\) は、\((d_i+1)\) 回目の実行時に訪れるが、初めて訪れるマスではない
    \(d_i\) の定義より \((X_i + d_ia, Y_i + d_ib) \in V_1\) なので\(1\)回目の実行時に訪問済み)
  • マス \((X_i + (d_i+1)a, Y_i + (d_i+1)b)\) は、\((d_i+2)\) 回目の実行時に訪れるが、初めて訪れるマスではない
    \((X_i + (d_i+1)a, Y_i + (d_i+1)b) = ((X_i+d_ia) + a, (Y_i+d_ib) + b)\) なので \(2\) 回目の実行時に訪問済み)
  • マス \((X_i + (d_i+2)a, Y_i + (d_i+2)b)\) は、\((d_i+3)\) 回目の実行時に訪れるが、初めて訪れるマスではない
    \((X_i + (d_i+2)a, Y_i + (d_i+2)b) = ((X_i+d_ia) + 2a, (Y_i+d_ib) + 2b)\) なので \(3\) 回目の実行時に訪問済み)
  • \(\cdots\)

となります。
よって、\(S\)\(K\) 回実行する際に、この \((X_i, Y_i)\) によって未訪問のマスが訪問済みに変わる回数は \(\min(d_i, K)\) 回です。

したがって、本問題の答えは、

\(\displaystyle\sum_{i = 1}^N \min(d_i, K)\)

です。

以上から、本問題はすべての \(i = 1, 2, \ldots, N\) について、\(d_i\) の値を求めることに帰着されます。これを高速に行う方法を以下に述べます。

\(a = b = 0\) のときは、\(d_1 = d_2 = \cdots = d_N = 1\) と分かります。 また、\(a = 0, b \neq 0\) の場合は \(X\) 座標と \(Y\) 座標の役割を交換することで、\(a \neq 0\) の場合に帰着できるので、以下では \(a \neq 0\) を仮定します。

まず \(i = 1, 2, \ldots, N\) ごとに、

\(q_i = \left\lfloor \displaystyle\frac{X_i}{a} \right\rfloor\)

\(s_i = X_i - q_i a\)

\(t_i = Y_i - q_i b\)

を計算し、\(V_1\) の要素を \((s_i, t_i)\) ごとにグループに分けます。 ( \((s_i, t_i) = (s_j, t_j)\) のときかつそのときに限り、\((X_i, Y_i)\)\((X_j, Y_j)\) が同じグループに属するようにグループ分けします。)

任意の \(1 \leq i, j \leq N\) ついて、

\((s_i, t_i) = (s_j, t_j) \Leftrightarrow (X_j, Y_j) = (X_i + (q_j-q_i)a, Y_i + (q_j-q_i)b)\)

が成り立つので、各グループ内で \(q_i\) によってソートすることで、「すべての \(i = 1, 2, \ldots, N\) について \(d_i\) の値を求める」ことが、\(\mathrm{O}(N\log N)\) 時間でできます。

以上より、この問題を \(\mathrm{O}(|S|\log|S|)\) 時間で解くことができます。

posted:
last update: