#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <numeric>
#include <stack>
#define hyathu main
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pint = int*;
constexpr int mmb = 1e5 + 9, mmn = 4e5 + 69, mmk = 101;
const ld pi = atan(1) * 4;
const ld golden = (1+sqrtl(5))/2;
int n, k;
ll a[mmb], dp[mmk][mmb], l[mmb], r[mmb];
//li = so dau tien lon hon ai o ben trai
//ri = ...
struct SegTree{
int n;
ll st[mmn];
void SetN(int N){
n = N;
fill(st + 1, st + 4 * n + 10, 9e18);
}
void DoUpdate(int l, int r, int id, const int &x, const ll &y){
if(l > x || r < x) return;
if(l == r){
st[id] = min(st[id], y);
return;
}
int mid = (l + r) / 2;
DoUpdate(l, mid, id * 2, x, y);
DoUpdate(mid + 1, r, id * 2 + 1, x, y);
st[id] = min(st[id * 2], st[id * 2 + 1]);
}
inline void update(const int &x, const ll &y){
DoUpdate(0, n + 1, 1, x, y);
}
ll Query(int l, int r, int id, int u, int v){
if(l > v || r < u)
return 9e18;
if(u <= l && r <= v)
return st[id];
int mid = (l + r) / 2;
return min(Query(l, mid, id * 2, u, v), Query(mid + 1, r, id * 2 + 1, u, v));
}
inline ll getMin(const int &x, const int &y){
return Query(0, n + 1, 1, x, y);
}
} segtree;
void readData(){
cin >> n >> k;
for(int i = 1; i <= n; ++i)
cin >> a[i];
}
void prepareLR(){
a[0] = a[n + 1] = 9e18;
stack <int> st;
st.push(0);
for(int i = 1; i <= n; ++i){
while(a[i] >= a[st.top()]) st.pop();
l[i] = st.top();
st.push(i);
}
while(!st.empty()) st.pop();
st.push(n + 1);
for(int i = n; i >= 1; --i){
while(a[i] >= a[st.top()]) st.pop();
r[i] = st.top();
st.push(i);
}
// for(int i = 1; i <= n; ++i) cout << l[i] << " ";
// cout << "\n";
// for(int i = 1; i <= n; ++i) cout << r[i] << " ";
// cout << "\n";
}
void solve(){
prepareLR();
//dp[j][i] = max(dp[j - 1][k] : (i > k & l[i] < r[k])
// -> update(r[i], dp[j][i])
// getMin(l[i] + 1, n + 1)
ll mx = -9e18;
for(int i = 1; i <= n; ++i)
dp[1][i] = mx = max(mx, a[i]);
for(int j = 2; j <= k; ++j){
segtree.SetN(n + 1);
segtree.update(r[j - 1], dp[j - 1][j - 1]);
for(int i = j; i <= n; ++i){
dp[j][i] = segtree.getMin(l[i] + 1, n + 1) + a[i];
segtree.update(r[i], dp[j - 1][i]);
}
}
// for(int j = 1; j <= k; ++j){
// for(int i = 1; i <= n; ++i){
// if(dp[j][i] == 9e18) cout << " * ";
// else cout << setw(3) << dp[j][i] << " ";
// }
// cout << "\n";
// }
ll ans = 9e18;
for(int i = k; i <= n; ++i)
if(r[i] >= n + 1)
ans = min(ans, dp[k][i]);
cout << ans;
}
#define filename "test"
int hyathu(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
#ifdef dangheo
freopen("test.inp", "r", stdin);
//freopen("test.out", "w", stdout);
#else
//freopen(filename".INP", "r", stdin);
//freopen(filename".OUT", "w", stdout);
#endif
readData();
solve();
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |