Submission #1208123

#TimeUsernameProblemLanguageResultExecution timeMemory
1208123gatapdevK개의 묶음 (IZhO14_blocks)C++20
53 / 100
1095 ms7708 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; const ll INF = LLONG_MAX / 4; // Bottom-up segment tree supporting range-add and range-min struct SegTree { int n; vector<ll> tree, lazy; SegTree(int _n) : n(_n), tree(2*n, INF), lazy(n, 0) {} // build from base array of size n+1 (0..n) void build(const vector<ll>& base) { for (int i = 0; i <= n; i++) tree[i + n] = base[i]; for (int i = n - 1; i >= 1; i--) tree[i] = min(tree[i<<1], tree[i<<1|1]); } // apply at position p void apply(int p, ll v) { tree[p] += v; if (p < n) lazy[p] += v; } // push from p void push(int p) { int h = __builtin_ctz(p); for (int s = h; s > 0; s--) { int i = p >> s; if (lazy[i]) { apply(i<<1, lazy[i]); apply(i<<1|1, lazy[i]); lazy[i] = 0; } } } // pull at p void pull(int p) { while (p > 1) { p >>= 1; tree[p] = min(tree[p<<1], tree[p<<1|1]) + lazy[p]; } } // range add [l, r] void range_add(int l, int r, ll v) { l += n; r += n; int l0 = l, r0 = r; for (; l <= r; l >>= 1, r >>= 1) { if (l&1) apply(l++, v); if (!(r&1)) apply(r--, v); } pull(l0); pull(r0); } ll range_min(int l, int r) { l += n; r += n; push(l); push(r); ll res = INF; for (; l <= r; l >>= 1, r >>= 1) { if (l&1) res = min(res, tree[l++]); if (!(r&1)) res = min(res, tree[r--]); } return res; } }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, K; cin >> n >> K; vector<ll> a(n+1); for (int i = 1; i <= n; i++) cin >> a[i]; vector<ll> dp_prev(n+1, INF), dp_cur(n+1, INF); dp_prev[0] = 0; // base k=1 for (int i = 1; i <= n; i++) dp_prev[i] = max(dp_prev[i-1], a[i]); SegTree st(n+1); for (int k = 2; k <= K; k++) { st = SegTree(n+1); st.build(dp_prev); vector<int> stk, left(n+1); for (int i = k; i <= n; i++) dp_cur[i] = INF; for (int i = k; i <= n; i++) { int L = i; while (!stk.empty() && a[stk.back()] <= a[i]) { int t = stk.back(); stk.pop_back(); int lt = left[t]; st.range_add(lt-1, t-1, -a[t]); L = lt; } stk.push_back(i); left[i] = L; st.range_add(L-1, i-1, a[i]); dp_cur[i] = st.range_min(k-1, i-1); } dp_prev.swap(dp_cur); } cout << dp_prev[n] << "\n"; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...