제출 #1353408

#제출 시각아이디문제언어결과실행 시간메모리
1353408Alex1298Lawn Mower (CEOI25_lawnmower)C++20
25 / 100
215 ms245764 KiB
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

long long mow(int N, int C, int B, std::vector<int> &A, std::vector<int> &V) {
    vector<long long> S(N + 2, 0);
    vector<long long> A_pref(N + 2, 0);
    
    // Precalcularea sumelor partiale
    for (int i = 1; i <= N; i++) {
        S[i] = S[i - 1] + V[i - 1];
        A_pref[i] = A_pref[i - 1] + A[i - 1];
    }

    long long MaxS = S[N];
    
    // Capacitatile mai mari decat iarba totala echivaleaza cu infinit
    long long C_eff = C;
    if (C_eff > MaxS + 2) {
        C_eff = MaxS + 2;
    }

    // Cost[x] = a_k + B, unde k este banda la care s-a atins cantitatea x de iarba
    vector<long long> Cost(MaxS + 2, 0);
    int current_lane = 1;
    for (long long x = 1; x <= MaxS; x++) {
        while (current_lane <= N && S[current_lane] < x) {
            current_lane++;
        }
        Cost[x] = A[current_lane - 1] + B;
    }

    // Array de penalizare a umplerii precalculat global
    vector<long long> Pref(MaxS + C_eff + 2, 0);
    for (long long x = 1; x <= MaxS; x++) {
        Pref[x] = Cost[x];
        if (x > C_eff) Pref[x] += Pref[x - C_eff];
    }
    for (long long x = MaxS + 1; x <= MaxS + C_eff; x++) {
        Pref[x] = Cost[MaxS] + Pref[x - C_eff];
    }

    auto get_Pref = [&](long long x) {
        if (x <= 0) return 0LL;
        return Pref[x];
    };

    vector<long long> dp(N + 2, 0);

    // THRESHOLDING
    if (C_eff <= 1500) {
        // Metoda 1: C este mic - DP pe resturi
        vector<long long> MinVal(C_eff, 1e18);
        for (int j = N; j >= 1; j--) {
            long long rem_j = (S[j] - 1) % C_eff;
            long long K_c = (S[j] - 1) - rem_j;
            long long val_base = A_pref[j] + dp[j + 1];

            for (long long r = 0; r <= rem_j; r++) {
                long long val = val_base + get_Pref(K_c + r);
                if (val < MinVal[r]) MinVal[r] = val;
            }
            long long K_minus_1_c = K_c - C_eff;
            for (long long r = rem_j + 1; r < C_eff; r++) {
                long long val = val_base + get_Pref(K_minus_1_c + r);
                if (val < MinVal[r]) MinVal[r] = val;
            }

            int i = j;
            long long r_i = S[i - 1] % C_eff;
            dp[i] = B - A_pref[i - 1] - get_Pref(S[i - 1]) + MinVal[r_i];
        }
    } else {
        // Metoda 2: C este mare - Sparse Table si Jumps
        vector<int> FirstGreater(MaxS + C_eff + 2, N + 1);
        int ptr = 1;
        for (long long x = 0; x <= MaxS + C_eff; x++) {
            while (ptr <= N && S[ptr] <= x) ptr++;
            FirstGreater[x] = ptr;
        }

        vector<int> Log2(N + 2, 0);
        for (int i = 2; i <= N + 1; i++) Log2[i] = Log2[i / 2] + 1;

        vector<vector<long long>> st(20, vector<long long>(N + 2, 1e18));

        for (int j = N; j >= 1; j--) {
            long long val = A_pref[j] + dp[j + 1];
            st[0][j] = val;
            for (int k = 1; k < 20; k++) {
                int next_idx = j + (1 << (k - 1));
                if (next_idx <= N) {
                    st[k][j] = min(st[k - 1][j], st[k - 1][next_idx]);
                } else {
                    st[k][j] = st[k - 1][j];
                }
            }

            int i = j;
            long long ans = 1e18;
            for (long long k_mult = 0; ; k_mult++) {
                long long X = S[i - 1] + k_mult * C_eff;
                if (X > S[N] - 1) break;
                
                int L = FirstGreater[X];
                int R = FirstGreater[X + C_eff] - 1;
                if (R > N) R = N;
                
                if (L <= R) {
                    int len = R - L + 1;
                    int k_log = Log2[len];
                    long long min_val = min(st[k_log][L], st[k_log][R - (1 << k_log) + 1]);
                    long long current_val = get_Pref(X) + min_val;
                    if (current_val < ans) ans = current_val;
                }
            }
            dp[i] = B - A_pref[i - 1] - get_Pref(S[i - 1]) + ans;
        }
    }
    return dp[1];
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…