Submission #1208125

#TimeUsernameProblemLanguageResultExecution timeMemory
1208125gatapdevK blocks (IZhO14_blocks)C++20
0 / 100
0 ms328 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = LLONG_MAX/4;

int n, K;
vector<ll> a;
vector<vector<ll>> stMax;
vector<int> log2v;

// Precompute sparse table for RMQ max
void buildSparse() {
    log2v.assign(n+2, 0);
    for (int i = 2; i <= n; i++) log2v[i] = log2v[i/2] + 1;
    int maxLog = log2v[n];
    stMax.assign(maxLog+1, vector<ll>(n+1));
    for (int i = 1; i <= n; i++) stMax[0][i] = a[i];
    for (int k = 1; k <= maxLog; k++) {
        for (int i = 1; i + (1<<k) - 1 <= n; i++) {
            stMax[k][i] = max(stMax[k-1][i], stMax[k-1][i + (1<<(k-1))]);
        }
    }
}

// Query max in a[l..r]
ll queryMax(int l, int r) {
    if (l > r) return 0;
    int len = r - l + 1;
    int k = log2v[len];
    return max(stMax[k][l], stMax[k][r - (1<<k) + 1]);
}

vector<ll> dp_prev, dp_cur;

void compute(int k, int L, int R, int optL, int optR) {
    if (L > R) return;
    int mid = (L + R) >> 1;
    ll bestVal = INF;
    int bestPos = -1;
    int start = max(k-1, optL);
    int end = min(mid-1, optR);
    for (int j = start; j <= end; j++) {
        ll val = dp_prev[j] + queryMax(j+1, mid);
        if (val < bestVal) {
            bestVal = val;
            bestPos = j;
        }
    }
    dp_cur[mid] = bestVal;
    // Recurse on left and right
    compute(k, L, mid-1, optL, bestPos);
    compute(k, mid+1, R, bestPos, optR);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> K;
    a.resize(n+1);
    for (int i = 1; i <= n; i++) cin >> a[i];

    buildSparse();
    dp_prev.assign(n+1, INF);
    dp_cur.assign(n+1, INF);
    dp_prev[0] = 0;
    // base k=1: prefix max
    for (int i = 1; i <= n; i++) dp_prev[i] = max(dp_prev[i-1], a[i]);

    // DP for k=2..K using divide-and-conquer optimization
    for (int k = 2; k <= K; k++) {
        compute(k, k, n, 0, n-1);
        dp_prev = 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...