結果
| 問題 |
No.1460 Max of Min
|
| コンテスト | |
| ユーザー |
KoD
|
| 提出日時 | 2021-03-31 22:26:57 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 753 ms / 2,000 ms |
| コード長 | 3,798 bytes |
| コンパイル時間 | 2,133 ms |
| コンパイル使用メモリ | 202,464 KB |
| 最終ジャッジ日時 | 2025-01-20 03:55:52 |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 91 |
ソースコード
#include <bits/stdc++.h>
using i32 = std::int32_t;
using u32 = std::uint32_t;
using i64 = std::int64_t;
using u64 = std::uint64_t;
using i128 = __int128_t;
using u128 = __uint128_t;
using isize = std::ptrdiff_t;
using usize = std::size_t;
class rep {
struct Iter {
usize itr;
constexpr Iter(const usize pos) noexcept: itr(pos) { }
constexpr void operator ++ () noexcept { ++itr; }
constexpr bool operator != (const Iter& other) const noexcept { return itr != other.itr; }
constexpr usize operator * () const noexcept { return itr; }
};
const Iter first, last;
public:
explicit constexpr rep(const usize first, const usize last) noexcept: first(first), last(std::max(first, last)) { }
constexpr Iter begin() const noexcept { return first; }
constexpr Iter end() const noexcept { return last; }
};
class revrep {
struct Iter {
usize itr;
constexpr Iter(const usize pos) noexcept: itr(pos) { }
constexpr void operator ++ () noexcept { --itr; }
constexpr bool operator != (const Iter& other) const noexcept { return itr != other.itr; }
constexpr usize operator * () const noexcept { return itr; }
};
const Iter first, last;
public:
explicit constexpr revrep(const usize first, const usize last) noexcept: first(last - 1), last(std::min(first, last) - 1) { }
constexpr Iter begin() const noexcept { return first; }
constexpr Iter end() const noexcept { return last; }
};
template <class T, T Div = 2>
constexpr T INFTY = std::numeric_limits<T>::max() / Div;
template <class T>
using Vec = std::vector<T>;
struct SemiRing {
static constexpr SemiRing zero() {
return SemiRing { -INFTY<i64> };
}
static constexpr SemiRing one() {
return SemiRing { INFTY<i64> };
}
i64 x;
constexpr SemiRing operator + (const SemiRing& other) const {
return SemiRing { std::max(x, other.x) };
}
constexpr SemiRing operator * (const SemiRing& other) const {
return SemiRing { std::min(x, other.x) };
}
};
void H_main() {
// O(K^2 log N) ?
// + ... max, x ... min の半環
// 中一でこんなの知ってるのか...
// kitamasa法 書いたことないんだが
// A[n+k] = B[0] * A[n] + B[1] * A[n+1] + ... + B[k-1] * A[n+k-1]
usize K;
u64 N;
std::cin >> K >> N;
Vec<SemiRing> A(K), B(K);
for (auto& x: A) {
std::cin >> x.x;
}
for (auto& x: B) {
std::cin >> x.x;
}
const auto next = [&](const Vec<SemiRing>& vec) {
Vec<SemiRing> ret(K, SemiRing::zero());
ret[0] = vec[K - 1] * B[0];
for (auto i: rep(0, K - 1)) {
ret[i + 1] = vec[i] + vec[K - 1] * B[i + 1];
}
return ret;
};
const auto dbl = [&](const Vec<SemiRing>& vec) {
Vec<Vec<SemiRing>> coeff(K, Vec<SemiRing>(K, SemiRing::zero()));
coeff[0] = vec;
for (auto i: rep(0, K - 1)) {
coeff[i + 1] = next(coeff[i]);
}
Vec<SemiRing> ret(K, SemiRing::zero());
for (auto i: rep(0, K)) {
for (auto j: rep(0, K)) {
ret[i] = ret[i] + coeff[0][j] * coeff[j][i];
}
}
return ret;
};
// C(K, *) = B
// C(0, *) = { 1, 0, 0, ..., 0 }
Vec<SemiRing> coeff(K, SemiRing::zero());
coeff[0] = SemiRing::one();
for (auto d: revrep(0, 64)) {
coeff = dbl(coeff);
if (N >> d & 1) {
coeff = next(coeff);
}
}
SemiRing ans = SemiRing::zero();
for (auto i: rep(0, K)) {
ans = ans + A[i] * coeff[i];
}
std::cout << ans.x << '\n';
return;
}
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
H_main();
return 0;
}
KoD