Monge / anti-Monge な行列と CHT / Li Chao Tree の関係
導入
行列 が Monge であるとは、以下の条件が成り立つことをいう。
- 及び を満たす全ての整数の組 について、 が成り立つ。
また、 なので、 である。
行列 が anti-Monge であるとは、以下の条件が成り立つことをいう。
- 及び を満たす全ての整数の組 について、 が成り立つ。
また同じように、 なので、 である。
アルゴリズム
Monge でも anti-Monge でも本質的には変わらないので、なんとなく後者について説明します。
より、全ての整数の組 について、 かつ を満たす が高々 1 つ存在します。存在しない場合は とすると、 について を満たし、 について を満たします。
Li Chao Tree
とおくと、先程の式は以下のようになります。
- について を満たし、 について を満たす
任意のペアについてこのような が存在するような関数群には Li Chao Tree が使えます。証明を求められるとどう書けばいいのか困るのですが (できると思う) 、ここに書いてあるということで許してください。
DAG の dp で使う場合
下三角行列なので定義域が怪しい感じになるのですが、結局 (最小値 / 最大値) クエリは定義域の中にしか飛ばさないので、適切な値で埋めれば大丈夫です。
嬉しい場合
- オンライン dp において Monge の最大値 / anti-Monge の最小値を求めるのには LARSCH が使えなくて、その場合オンライン - オフライン変換 + SMAWK よりも定数倍が速いと思う。
- SMAWK の書き方を忘れてしまったとき。
- Monge な行列の列がランダムな順番で追加されるので (!?!?!?!?) min / max を求めたいとき。
- 変なタイミングで謎の位置での最小値を求めたいとき。これは辺の重み関数が Monge かつ別のいい感じの、例えば極値が高々 1 つみたいな性質を持っている (DAG ではない) 一般の完全グラフの最短経路を求めるときに使える場合があると思っている。
Convex Hull Trick のアイデアの適用
なんだか上で満足してしまったような気分ですが、一応。
No.1867 Partitions and Inversions - yukicoder の解説はこれの特殊ケースです。
Li Chao Tree と同じく、 Monge / anti-Monge の場合ではほとんど Convex Hull Trick のロジックがそのまま使えるのですが、いくつか問題点があります。
連続する 3 つの関数のうち中央がいらない場合の判定
一次関数だとこれは定数時間でできるのですが、一般に Monge / anti-Monge となると困ります。二分探索をすればなんとかなります。なので、いわゆる「追加と質問がどちらも単調な場合」にもならし定数時間にはならない、と思っています。(特に anti-Monge でなったら LARSCH と同じ線形時間が達成できることになって、そんなことはなさそう)
うれしい場合 :
— tatyam (@tatyam_prime) 2023年8月7日
曲線 2 つの交点が高速に (O(1) で) 求まる場合, あるいはより広く, 2 つの曲線に挟まれた曲線が必要かどうかが高速に求まる場合, LARSCH より速い
追加クエリが (元の CHT でいう) 単調でない場合
こんな場合ある ??? という気持ちですが......。
CHT の場合、傾きで二分探索をして挿入するべき位置を特定していました。一般に Monge だと困ります。
行列 が Monge であり、その 行目の任意の要素にアクセスできるので、 の大小を比較したい、という問題を考えます。これは、 行目かつ 列目である にアクセスできればよいです。この 4 要素からなる部分行列が Monge かつ anti-Monge である場合は決定できないのですが、その場合決定しないでも問題ないです。
これで比較ができるようになったので、結局 std::map などで二分探索を用いることができます。
うれしい場合
- 書きやすい ?
- 条件によっては定数倍がいい気がする。