Cod sursa(job #1701375)

Utilizator RazvanR104Razvan-Andrei Ciocoiu RazvanR104 Data 12 mai 2016 21:43:31
Problema Deque Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 4.78 kb
#include <bits/stdc++.h>

using namespace std;

template<typename T>
class Deque {
    public:
        Deque(const int BUCKET_SIZE):
            BUCKET_SIZE(BUCKET_SIZE),
            link(new T*),
            l_list(0),
            r_list(0),
            l_pos(-1),
            r_pos(-1),
            curr_l(1),
            d_size(0) {
            link[0] = new T[BUCKET_SIZE];
            link[1] = new T[BUCKET_SIZE];
        }

        const int size() const {
            return d_size;
        }

        void pop_back() {
            if (d_size == 0)
                throw 1337;
            if (--d_size == 0)
                reset();
            else
                decrement(r_list, r_pos);
        }

        void pop_front() {
            if (d_size == 0)
                throw 1337;
            if (--d_size == 0)
                reset();
            else
                advance(l_list, l_pos);
        }

        void push_back(const T &value) {
            if (l_pos == -1 && r_pos == -1) {
                l_pos = r_pos = 0;
                link[l_list][l_pos] = value;
                d_size = 1;
                return;
            }
            ++d_size;
            advance(r_list, r_pos);
            link[r_list][r_pos] = value;
        }

        void push_front(const T &value) {
            if (l_pos == -1 && r_pos == -1) {
                l_pos = r_pos = 0;
                link[l_list][l_pos] = value;
                d_size = 1;
                return;
            }
            ++d_size;
            decrement(l_list, l_pos);
            link[l_list][l_pos] = value;
        }

        const T back() const {
            if (d_size == 0)
                throw 1337;
            return link[r_list][r_pos];
        }

        const T front() const {
            if (d_size == 0)
                throw 1337;
            return link[l_list][l_pos];
        }

        T& operator[](int index) {
            ++index;
            if (index > d_size)
                throw 1337;

            int c_list = l_list, c_pos = l_pos;
            if (c_pos + index - 1 < BUCKET_SIZE)
                return link[c_list][c_pos + index - 1];
            else {
                ++c_list;
                index -= BUCKET_SIZE - c_pos;
                c_pos = 0;
            }

            c_list += index / BUCKET_SIZE;
            index %= BUCKET_SIZE;

            if (index == 0)
                return link[c_list - 1][BUCKET_SIZE - 1];
            return link[c_list][index - 1];
        }

    private:
        const int BUCKET_SIZE;
        T **link;
        int l_list, r_list, l_pos, r_pos;
        int curr_l;
        int d_size;

        void reset() {
            l_list = r_list = curr_l / 2;
            l_pos = r_pos = -1;
        }

        void advance(int &listnum, int &pos) {
            ++pos;
            if (pos == BUCKET_SIZE) {
                pos = 0;
                ++listnum;
            }

            if (listnum >= curr_l) {
                ++curr_l;
                T **temp = new T *[curr_l];
                //for (int i = 0; i < curr_l; ++i)
                //    temp[i] = link[i];
                memcpy(temp, link, (curr_l - 1) * sizeof(T*));
                temp[curr_l - 1] = new T[BUCKET_SIZE];
                delete link;
                link = temp;
            }
        }

        void decrement(int &listnum, int &pos) {
            --pos;
            if (pos == -1) {
                pos = BUCKET_SIZE - 1;
                --listnum;
            }

            if (listnum < 0) {
                ++curr_l;
                T **temp = new T *[curr_l];
                //for (int i = 1; i < curr_l + 1; ++i)
                //    temp[i] = link[i - 1];
                memcpy(temp + 1, link, (curr_l - 1) * sizeof(T*));
                temp[0] = new T[BUCKET_SIZE];
                delete link;
                link = temp;
                ++l_list;
                ++r_list;
            }
        }
};

int main() {
    assert(freopen("deque.in", "r", stdin));
    assert(freopen("deque.out", "w", stdout));

    int N, K;
    int value, i;

    scanf("%d %d", &N, &K);
    Deque<pair<int, int>> D(1e6);
    for (i = 1; i <= K; ++i) {
        scanf("%d", &value);
        while (D.size() && value <= D.back().first)
            D.pop_back();
        D.push_back({value, i});
    }

    int64_t answer = D.front().first;
    for (i = K + 1; i <= N; ++i) {
        scanf("%d", &value);
        while (D.size() && value <= D.back().first)
            D.pop_back();
        D.push_back({value, i});
        if (i - D.front().second + 1 > K)
            D.pop_front();
        answer += D.front().first;
    }

    cout << answer << '\n';
    return 0;
}