#include "peru.h"
#include "bits/stdc++.h"
namespace {
#ifdef DEBUG
#include "/home/ahmetalp/Desktop/Workplace/debug.h"
#else
#define debug(...) void(23)
#endif
using i64 = long long;
constexpr i64 inf = i64(1E18);
constexpr int md = int(1E9) + 7;
#define def int mid = (l + r) >> 1, lv = v + 1, rv = v + ((mid - l + 1) << 1)
struct segtree {
int n;
std::vector<i64> tree;
segtree(int n_) : n(n_), tree(n << 1, inf) {}
void set(int v, int l, int r, int p, i64 x) {
if (l == r) {
tree[v] = x;
return;
}
def;
if (p <= mid) {
set(lv, l, mid, p, x);
} else {
set(rv, mid + 1, r, p, x);
}
tree[v] = std::min(tree[lv], tree[rv]);
}
void set(int p, i64 x) {
set(0, 0, n - 1, p, x);
}
i64 get(int v, int l, int r, int ql, int qr) {
if (ql == l && r == qr) {
return tree[v];
}
def;
if (qr <= mid) {
return get(lv, l, mid, ql, qr);
} else if (mid + 1 <= ql) {
return get(rv, mid + 1, r, ql, qr);
} else {
return std::min(get(lv, l, mid, ql, mid), get(rv, mid + 1, r, mid + 1, qr));
}
}
i64 get(int l, int r) {
return get(0, 0, n - 1, l, r);
}
};
};
int solve(int N, int K, int* A){
std::vector<i64> f(N + 1, inf);
f[0] = 0;
// segtree seg(N + 1);
// seg.set(0, 0);
// std::vector<int> stk {-1};
std::vector<int> stk;
std::vector<int> prv(N);
for (int i = 0; i < N; ++i) {
while (!stk.empty() && A[stk.back()] <= A[i]) {
stk.pop_back();
}
prv[i] = stk.empty() ? -1 : stk.back();
stk.emplace_back(i);
}
debug(prv);
std::deque<int> deq;
segtree seg(N);
std::set<i64> mset {inf};
for (int i = 1; i <= N; ++i) {
debug(i, deq, mset);
if (deq.front() == i - K - 1) {
int x = deq.front();
if (prv[x] <= i - K) {
mset.erase(mset.find(A[x]));
} else {
seg.set(x, inf);
}
deq.pop_front();
}
debug(__LINE__);
while (!deq.empty() && A[deq.back()] <= A[i - 1]) {
int x = deq.back();
debug(x, prv[x]);
if (prv[x] < i - K) {
mset.erase(mset.find(A[x]));
} else {
seg.set(x, inf);
}
deq.pop_back();
}
debug(__LINE__);
if (!deq.empty() && prv[deq.front()] + 1 == i - K) {
seg.set(deq.front(), inf);
mset.emplace(A[deq.front()]);
}
auto eval = [&](int x) -> i64 {
return f[std::max(prv[x] + 1, i - K)] + A[x];
};
debug(__LINE__);
int x = i - 1;
if (prv[x] + 1 <= i - K) {
mset.emplace(A[x]);
} else {
seg.set(x, eval(i - 1));
}
deq.emplace_back(i - 1);
debug(__LINE__);
debug(i, deq, mset);
f[i] = seg.get(0, N - 1);
f[i] = std::min(f[i], *mset.begin() + f[std::max(0, i - K)]);
// for (auto j : deq) {
// debug(j, eval(j));
// f[i] = std::min(f[i], eval(j));
// }
#ifdef LOCAL
int mx = 0;
i64 real = inf;
for (int j = i; j >= std::max(1, i - K + 1); --j) {
mx = std::max(mx, A[j - 1]);
real = std::min(real, f[j - 1] + mx);
}
mx = 0;
for (int j = i; j >= std::max(1, i - K + 1); --j) {
mx = std::max(mx, A[j - 1]);
real = std::min(real, f[j - 1] + mx);
if (real == f[j - 1] + mx) {
debug(i, j - 1);
}
}
debug(real, f[i]);
assert(real == f[i]);
#endif
}
int ans = 0;
for (int i = 0; i < N; ++i) {
int x = f[i + 1] % md;
debug(i, x);
ans = (ans * 23LL + x) % md;
}
return ans;
}
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |