This documentation is automatically generated by online-judge-tools/verification-helper
#include "src/dp/monotone_minima.hpp"
vector<int> monotome_minima<F>(int n, int m, F f)
$n \times m$ のmonotone行列 $A$ に対して,各行における最小値を取る列を列挙します.
以下の要件を満たす関数 bool f(int i, int j, int k)
を定義する必要があります.
true
を返す ( $j < k$ が保証される.等号はどちらでもよい).計算量
#pragma once
#include "../template/template.hpp"
template <class F>
vector<int> monotone_minima(const int n, const int m, const F& f) {
vector<int> res(n);
auto dfs = [&](const auto& dfs, const int is, const int ie, const int l, const int r) -> void {
if(is == ie) return;
const int i = (is + ie) / 2;
int m = l;
for(int k = l + 1; k < r; ++k) {
if(!f(i, m, k)) m = k;
}
res[i] = m;
dfs(dfs, is, i, l, m + 1);
dfs(dfs, i + 1, ie, m, r);
};
dfs(dfs, 0, n, 0, m);
return res;
}
#line 2 "src/template/template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<long long, long long>;
#define rep(i, a, b) for(long long i = (a); i < (b); ++i)
#define rrep(i, a, b) for(long long i = (a); i >= (b); --i)
constexpr long long inf = 4e18;
struct SetupIO {
SetupIO() {
ios::sync_with_stdio(0);
cin.tie(0);
cout << fixed << setprecision(30);
}
} setup_io;
#line 3 "src/dp/monotone_minima.hpp"
template <class F>
vector<int> monotone_minima(const int n, const int m, const F& f) {
vector<int> res(n);
auto dfs = [&](const auto& dfs, const int is, const int ie, const int l, const int r) -> void {
if(is == ie) return;
const int i = (is + ie) / 2;
int m = l;
for(int k = l + 1; k < r; ++k) {
if(!f(i, m, k)) m = k;
}
res[i] = m;
dfs(dfs, is, i, l, m + 1);
dfs(dfs, i + 1, ie, m, r);
};
dfs(dfs, 0, n, 0, m);
return res;
}