This documentation is automatically generated by competitive-verifier/competitive-verifier
#include "src/Optimization/monotone_minima.hpp"
名前 | 概要 | 計算量 |
---|---|---|
monotone_minima(H,W,select) |
monotone な $H\times W$ 行列に対して実行. 行列は陽には与えず select 関数を渡す.select(i,j,k) は $(i,j)$ -成分より $(i,k)$ -成分の方が望ましいなら true を返すという関数. ただし,呼ばれるときは必ず $j\lt k$.返り値は各行 $i$ に対して最適解を達成する列方向 $j$ を返す. |
$O((H+W)\log H)$ |
https://topcoder-g-hatena-ne-jp.jag-icpc.org/spaghetti_source/20120923/1348327542.html
#pragma once
#include <vector>
// select(i,j,k) -> true if (i,k) is better than (i,j)
template <typename F> std::vector<int> monotone_minima(int H, int W, const F &select) {
std::vector<int> ret(H);
auto rec= [&](auto &rec, int h1, int h2, int w1, int w2) -> void {
if (h1 == h2) return;
int h= (h1 + h2) / 2, best_w= w1;
for (int w= w1 + 1; w < w2; ++w)
if (select(h, best_w, w)) best_w= w;
ret[h]= best_w, rec(rec, h1, h, w1, best_w + 1), rec(rec, h + 1, h2, best_w, w2);
};
return rec(rec, 0, H, 0, W), ret;
}
#line 2 "src/Optimization/monotone_minima.hpp"
#include <vector>
// select(i,j,k) -> true if (i,k) is better than (i,j)
template <typename F> std::vector<int> monotone_minima(int H, int W, const F &select) {
std::vector<int> ret(H);
auto rec= [&](auto &rec, int h1, int h2, int w1, int w2) -> void {
if (h1 == h2) return;
int h= (h1 + h2) / 2, best_w= w1;
for (int w= w1 + 1; w < w2; ++w)
if (select(h, best_w, w)) best_w= w;
ret[h]= best_w, rec(rec, h1, h, w1, best_w + 1), rec(rec, h + 1, h2, best_w, w2);
};
return rec(rec, 0, H, 0, W), ret;
}