#include <climits>
#include <cstdint>
#include <functional>
#include <iostream>
#include <vector>
#define FAST_IO
#ifdef FAST_IO
char readchar() {
char c = getchar();
while (c <= 33) {
c = getchar();
}
return c;
}
int readint() {
char c = getchar();
while (c <= 33) {
c = getchar();
}
bool sign = false;
if (c == '-') {
sign = true;
c = getchar();
}
int t = 0;
while (c >= '0' && c <= '9') {
t = (t << 3) + (t << 1) + c - '0';
c = getchar();
}
return (sign ? -t : t);
}
#endif
class segment_tree
{
public:
static const int INF = 200000000;
segment_tree(size_t n_, int val = 0);
void maximize(size_t l, size_t r, int val)
{
if (r >= n || l > r) throw;
maximize_(1, 0, n - 1, l, r, val);
}
// Undefined behavior, if not all trees have equal segment_tree::n.
friend void group_maximize(size_t l, size_t r,
std::vector<segment_tree *> & trees, const std::vector<int> & val)
{
if (trees.empty()) return;
if (trees.size() != val.size()) throw;
if (r >= trees[0] -> n || l > r) throw;
group_maximize_(1, 0, trees[0] -> n - 1, l, r, trees, val);
}
int operator[](size_t ind)
{
return at_ind(ind);
}
int at_ind(size_t ind)
{
if (ind >= n) throw;
return at_ind_(1, 0, n - 1, ind);
}
int max_elem(size_t l, size_t r)
{
if (r >= n || l > r) throw;
return max_elem_(1, 0, n - 1, l, r);
}
// Undefined behavior, if not all trees have equal segment_tree::n.
friend void group_max_elem(size_t l, size_t r,
std::vector<segment_tree *> & trees, std::vector<int> & res)
{
if (trees.empty()) return;
if (r >= trees[0] -> n || l > r) throw;
res.resize(trees.size(), -INF);
return group_max_elem_(1, 0, trees[0] -> n - 1, l, r, trees, res);
}
void push(int v);
private:
typedef std::int_least8_t ibool_t; // Stored in containers which don't fully support bool.
void maximize_(int v, size_t vl, size_t vr, size_t l, size_t r, int val);
friend void group_maximize_(int v, size_t vl, size_t vr, size_t l, size_t r,
std::vector<segment_tree *> & trees, const std::vector<int> & val);
int at_ind_(int v, size_t vl, size_t vr, size_t ind);
int max_elem_(int v, size_t vl, size_t vr, size_t l, size_t r);
friend void group_max_elem_(int v, size_t vl, size_t vr, size_t l, size_t r,
std::vector<segment_tree *> & trees, std::vector<int> & res);
size_t n;
std::vector<int> tree;
std::vector<ibool_t> is_lazy;
std::vector<int> lazy;
};
segment_tree::segment_tree(size_t n_, int val):
n(n_)
{
try
{
if (!n) throw;
tree.resize(n_ * 4, val);
lazy.resize(n_ * 4, false);
is_lazy.resize(n_ * 4, false);
}
catch (...)
{
std::abort();
}
}
void segment_tree::maximize_(int v, size_t vl, size_t vr, size_t l, size_t r, int val)
{
if (vl == l && vr == r)
{
if (!is_lazy[v] || val > lazy[v])
{
lazy[v] = val;
is_lazy[v] = true;
}
return;
}
push(v);
size_t vm = vl + (vr - vl) / 2;
if (r <= vm)
maximize_(2 * v, vl, vm, l, r, val);
else if (l > vm)
maximize_(2 * v + 1, vm + 1, vr, l, r, val);
else
{
maximize_(2 * v, vl, vm, l, vm, val);
maximize_(2 * v + 1, vm + 1, vr, vm + 1, r, val);
}
push(2 * v);
push(2 * v + 1);
if (tree[2 * v] > tree[v]) tree[v] = tree[2 * v];
if (tree[2 * v + 1] > tree[v]) tree[v] = tree[2 * v + 1];
}
int segment_tree::at_ind_(int v, size_t vl, size_t vr, size_t ind)
{
push(v);
if (vl == vr)
return tree[v];
size_t vm = vl + (vr - vl) / 2;
if (ind <= vm)
return at_ind_(2 * v, vl, vm, ind);
else
return at_ind_(2 * v + 1, vm + 1, vr, ind);
}
int segment_tree::max_elem_(int v, size_t vl, size_t vr, size_t l, size_t r)
{
push(v);
if (vl == l && vr == r)
return tree[v];
size_t vm = vl + (vr - vl) / 2;
if (r <= vm)
return max_elem_(2 * v, vl, vm, l, r);
else if (l > vm)
return max_elem_(2 * v + 1, vm + 1, vr, l, r);
else
{
return std::max(max_elem_(2 * v, vl, vm, l, vm),
max_elem_(2 * v + 1, vm + 1, vr, vm + 1, r));
}
}
void segment_tree::push(int v)
{
if (is_lazy[v])
{
if (2 * v + 1 < tree.size())
{
is_lazy[2 * v] = is_lazy[2 * v + 1] = true;
lazy[2 * v] = lazy[2 * v + 1] = lazy[v];
}
if (lazy[v] > tree[v]) tree[v] = lazy[v];
is_lazy[v] = false;
}
}
size_t max_fine(int l, int r, std:: function < bool(size_t) > is_fine)
{
int st_l = l;
while (l + 1 < r)
{
size_t m = l + (r - l) / 2;
if (is_fine(m))
l = m;
else
r = m - 1;
}
if (r >= st_l && is_fine(r)) return r;
if (l >= st_l && is_fine(l)) return l;
return r + 1;
}
size_t min_fine(size_t l, size_t r, std:: function < bool(size_t) > is_fine)
{
size_t st_r = r;
while (l + 1 < r)
{
size_t m = l + (r - l) / 2;
if (is_fine(m))
r = m;
else
l = m + 1;
}
if (l <= st_r && is_fine(l)) return l;
if (r <= st_r && is_fine(r)) return r;
return r + 1;
}
void group_max_elem_(int v, size_t vl, size_t vr, size_t l, size_t r,
std::vector<segment_tree *> & trees, std::vector<int> & res)
{
for (size_t i = 0; i < trees.size(); ++i)
trees[i] -> push(v);
if (vl == l && vr == r)
{
for (size_t i = 0; i < trees.size(); ++i)
res[i] = std::max(res[i], trees[i] -> tree[v]);
return;
}
size_t vm = vl + (vr - vl) / 2;
if (r <= vm)
group_max_elem_(2 * v, vl, vm, l, r, trees, res);
else if (l > vm)
group_max_elem_(2 * v + 1, vm + 1, vr, l, r, trees, res);
else
{
group_max_elem_(2 * v, vl, vm, l, vm, trees, res);
group_max_elem_(2 * v + 1, vm + 1, vr, vm + 1, r, trees, res);
}
}
void group_maximize_(int v, size_t vl, size_t vr, size_t l, size_t r,
std::vector<segment_tree *> & trees, const std::vector<int> & val)
{
if (vl == l && vr == r)
{
for (size_t i = 0; i < trees.size(); ++i)
{
segment_tree & ST = *trees[i];
if (!ST.is_lazy[v] || val[i] > ST.lazy[v])
{
ST.lazy[v] = val[i];
ST.is_lazy[v] = true;
}
}
return;
}
for (size_t i = 0; i < trees.size(); ++i)
trees[i] -> push(v);
size_t vm = vl + (vr - vl) / 2;
if (r <= vm)
group_maximize_(2 * v, vl, vm, l, r, trees, val);
else if (l > vm)
group_maximize_(2 * v + 1, vm + 1, vr, l, r, trees, val);
else
{
group_maximize_(2 * v, vl, vm, l, vm, trees, val);
group_maximize_(2 * v + 1, vm + 1, vr, vm + 1, r, trees, val);
}
for (size_t i = 0; i < trees.size(); ++i)
{
segment_tree &ST = *trees[i];
ST.push(2 *v);
ST.push(2 *v + 1);
if (ST.tree[2 * v] > ST.tree[v])
ST.tree[v] = ST.tree[2 * v];
if (ST.tree[2 * v + 1] > ST.tree[v])
ST.tree[v] = ST.tree[2 * v + 1];
}
}
int main()
{
// Fast input/output.
std::ios::sync_with_stdio(0);
std::cin.tie(0);
std::cout.tie(0);
//
size_t N, K;
#ifdef FAST_IO
N = readint(); K = readint();
#else
std::cin >> N >> K;
#endif
segment_tree a(N, 0);
std::vector<int> arr(N);
for (size_t i = 0; i < N; ++i)
{
#ifdef FAST_IO
arr[i] = readint();
#else
std::cin >> arr[i];
#endif
a.maximize(i, i, arr[i]);
}
std::vector<segment_tree> dp(K + 1, segment_tree(N, -segment_tree::INF));
for (size_t i = 0; i < N; ++i)
{
dp[1].maximize(i, i, -a.max_elem(0, i));
size_t l = min_fine(0, i, [i, &arr, &a](size_t L) -> bool
{
return arr[i] >= a.max_elem(L, i);
});
std::vector<segment_tree *> trees;
trees.reserve(std::min(K, i + 1));
for (size_t k = 1; k < K && k <= i; ++k)
trees.push_back(&dp[k]);
std::vector<int> val;
group_max_elem(l ? l - 1 : 0, i - 1, trees, val);
for (size_t k = 1; k < K && k <= i; ++k)
val[k - 1] = -(arr[i] + -val[k - 1]);
trees.clear();
for (size_t k = 2; k <= K && k <= i + 1; ++k)
trees.push_back(&dp[k]);
group_maximize(i, i, trees, val);
size_t r = max_fine(i, N - 1, [i, &arr, &a](size_t R) -> bool
{
return arr[i] >= a.max_elem(i, R);
});
for (size_t k = 1; k <= K; ++k)
dp[k].maximize(i, r, dp[k][i]);
#if 0 // DEBUG lines.
for (size_t j = 0; j < N; ++j)
{
std::cerr << j << ": ";
for (size_t k = 1; k <= K; ++k)
if (-dp[k][j] < INF)
std::cerr << -dp[k][j] << ' ';
else
std::cerr << "INF ";
std::cerr << "\n";
}
std::cerr << "\n";
#endif // DEBUG lines.
}
int ans = segment_tree::INF;
for (size_t i = 0; i < N; ++i)
if (a.max_elem(i, N - 1) == arr[i])
ans = std::min(ans, -dp[K][i]);
std::cout << ans << std::endl;
}
Compilation message
blocks.cpp: In member function 'void segment_tree::push(int)':
blocks.cpp:179:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
if (2 * v + 1 < tree.size())
~~~~~~~~~~^~~~~~~~~~~~~
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
376 KB |
Output is correct |
2 |
Correct |
2 ms |
376 KB |
Output is correct |
3 |
Correct |
2 ms |
376 KB |
Output is correct |
4 |
Correct |
2 ms |
376 KB |
Output is correct |
5 |
Correct |
2 ms |
504 KB |
Output is correct |
6 |
Correct |
2 ms |
376 KB |
Output is correct |
7 |
Correct |
2 ms |
376 KB |
Output is correct |
8 |
Correct |
2 ms |
376 KB |
Output is correct |
9 |
Correct |
2 ms |
376 KB |
Output is correct |
10 |
Correct |
2 ms |
376 KB |
Output is correct |
11 |
Correct |
2 ms |
380 KB |
Output is correct |
12 |
Correct |
2 ms |
376 KB |
Output is correct |
13 |
Correct |
2 ms |
376 KB |
Output is correct |
14 |
Correct |
2 ms |
376 KB |
Output is correct |
15 |
Correct |
2 ms |
376 KB |
Output is correct |
16 |
Correct |
2 ms |
376 KB |
Output is correct |
17 |
Correct |
2 ms |
376 KB |
Output is correct |
18 |
Correct |
2 ms |
376 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
376 KB |
Output is correct |
2 |
Correct |
2 ms |
376 KB |
Output is correct |
3 |
Correct |
2 ms |
376 KB |
Output is correct |
4 |
Correct |
2 ms |
376 KB |
Output is correct |
5 |
Correct |
2 ms |
376 KB |
Output is correct |
6 |
Correct |
2 ms |
376 KB |
Output is correct |
7 |
Correct |
2 ms |
376 KB |
Output is correct |
8 |
Correct |
2 ms |
376 KB |
Output is correct |
9 |
Correct |
2 ms |
376 KB |
Output is correct |
10 |
Correct |
2 ms |
376 KB |
Output is correct |
11 |
Correct |
2 ms |
376 KB |
Output is correct |
12 |
Correct |
2 ms |
376 KB |
Output is correct |
13 |
Correct |
2 ms |
376 KB |
Output is correct |
14 |
Correct |
2 ms |
376 KB |
Output is correct |
15 |
Correct |
2 ms |
376 KB |
Output is correct |
16 |
Correct |
2 ms |
376 KB |
Output is correct |
17 |
Correct |
2 ms |
380 KB |
Output is correct |
18 |
Correct |
2 ms |
376 KB |
Output is correct |
19 |
Correct |
2 ms |
376 KB |
Output is correct |
20 |
Correct |
2 ms |
376 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
4 ms |
504 KB |
Output is correct |
2 |
Correct |
2 ms |
376 KB |
Output is correct |
3 |
Correct |
2 ms |
376 KB |
Output is correct |
4 |
Correct |
2 ms |
376 KB |
Output is correct |
5 |
Correct |
2 ms |
376 KB |
Output is correct |
6 |
Correct |
2 ms |
376 KB |
Output is correct |
7 |
Correct |
2 ms |
404 KB |
Output is correct |
8 |
Correct |
2 ms |
376 KB |
Output is correct |
9 |
Correct |
2 ms |
376 KB |
Output is correct |
10 |
Correct |
2 ms |
376 KB |
Output is correct |
11 |
Correct |
2 ms |
380 KB |
Output is correct |
12 |
Correct |
2 ms |
376 KB |
Output is correct |
13 |
Correct |
3 ms |
504 KB |
Output is correct |
14 |
Correct |
3 ms |
504 KB |
Output is correct |
15 |
Correct |
5 ms |
760 KB |
Output is correct |
16 |
Correct |
5 ms |
764 KB |
Output is correct |
17 |
Correct |
4 ms |
552 KB |
Output is correct |
18 |
Correct |
5 ms |
760 KB |
Output is correct |
19 |
Correct |
5 ms |
760 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
199 ms |
10488 KB |
Output is correct |
2 |
Correct |
363 ms |
6776 KB |
Output is correct |
3 |
Correct |
541 ms |
16248 KB |
Output is correct |
4 |
Execution timed out |
1085 ms |
124736 KB |
Time limit exceeded |
5 |
Halted |
0 ms |
0 KB |
- |