概要
端の移動回数が 以下の Mo's Algorithm を思いついたので紹介する。
通常の Mo's Algorithm
Mo's Algorithm の問題設定は以下のように言い換えられる。
を満たす格子点 が 個与えられる。 から始めて全ての点を通る経路を構成せよ。 経路の長さはマンハッタン距離で測られ、短いほど良い。
スタートが だけではなく任意の に対する であるとか、色々と実用に即したバリエーションは考えられるが、基本的に の変化しかないと思う。
通常の Mo's Algorithm は以下のように経路を構成する。
つまり、 を幅 毎に分け、同じ分類の点を の順に廻る。 また、 の昇降は交互に変化させる。 このとき経路長は 以下となり、 とすれば 以下となる。
改善された Mo's Algorithm
を幅 で分けた領域を帯と呼ぶことにする。 Mo's Algorithm の最悪ケースは、点が帯の両端に分布している場合である。 しかしこの場合、隣り合う帯の端にある点をまとめて通ってしまえばむしろ普通より短くなることが分かる。 この発想で、全ての帯を だけずらした Mo's Algorithm を実行し、元のものとのうち短い方の経路を選ぶというアルゴリズムを考える。
このアルゴリズムの価値は、 座標の変化量を より精密に評価することで明らかになる。 の帯について、 を帯の中央と呼ぶことにする。 経路を「中央を通って次に訪れたい点と 座標を揃えたのち、 座標を揃え、再び中央に戻る」ものとして解析しても問題ない *1。 すると、各点 の 座標に関する経路長への寄与は、属する帯の中央を として と評価できる。 は最悪で になり得るが、 通りの経路におけるそれを合計すると、常に になることが分かる (!)。 よって 通りの経路の長さの和は であり、 とすれば で抑えられる。 このうち短い方は 以下である。
最適性
このように点を配置する。 赤い点は 辺に 個配置しており合計で 個、青い点と併せて 個となる。 どの 点も のマンハッタン距離があることが分かるから、どのような経路も の長さが必要となる。 実際には が整数とは限らないこと、格子点にしか点を置けないこと、を考えると の下限を得る。 よって、前述したアルゴリズムは の差を除いて最適である *2。
Rollback Mo
参考: https://snuke.hatenablog.com/entry/2016/07/01/000000
同様の考え方を使うと、Rollback Mo も (Rollback も含めるとこの 倍) になる。 ただしこちらは最適なのか分からない。 必ず 程度必要になるケースは発見した。
ランダムケースにおける Mo's Algorithm
参考: https://nyaannyaan.github.io/library/misc/mo.hpp.html
ランダムケースでは まで落ちる。