Cod sursa(job #2885641)

Utilizator AndreiAncutaAndrei Ancuta AndreiAncuta Data 6 aprilie 2022 12:43:56
Problema Deque Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.18 kb
#include <stdexcept>
#include <fstream>

template <typename T> struct Node {
    Node *next = nullptr;
    Node *prev = nullptr;
    T value;
};

template <typename T> class Deque {
    Node<T> *frontNode;
    Node<T> *backNode;
    std::size_t _size = 0;

public:
    bool empty() const {
        return size() == 0;
    }

    std::size_t size() const {
        return _size;
    }

    T front() const {
        if (empty()) {
            throw std::out_of_range("Deque is empty");
        }
        return frontNode->value;
    }

    T back() const {
        if (empty()) {
            throw std::out_of_range("Deque is empty");
        }
        return backNode->value;
    }

    void push_front(T value) {
        Node<T> *newNode = new Node<T>();
        newNode->value = value;
        newNode->next = frontNode;

        if (empty()) {
            frontNode = backNode = newNode;
        } else {
            frontNode->prev = newNode;
            frontNode = newNode;
        }
        _size++;
    }

    void push_back(T value) {
        auto newNode = new Node<T>;
        newNode->value = value;
        newNode->prev = backNode;

        /* std::cerr << frontNode << " " << backNode << '\n'; */
        if (empty()) {
            frontNode = backNode = newNode;
        } else {
            backNode->next = newNode;
            backNode = newNode;
        }
        /* std::cerr << frontNode->value.value << " " << backNode->value.value << '\n'; */
        _size++;
    }

    T pop_front() {
        if (empty()) {
            throw std::out_of_range("No element to pop");
        }

        auto oldNode = frontNode;
        frontNode = frontNode->next;

        if (frontNode != nullptr) {
            frontNode->prev = nullptr;
        } else {
            // Deque is empty
            backNode = nullptr;
        }

        auto oldValue = oldNode->value;
        delete oldNode;
        _size--;
        /* std::cerr << "Pop front: " << frontNode << " " << backNode << '\n'; */
        return oldValue;
    }

    T pop_back() {
        if (empty()) {
            throw std::out_of_range("No element to pop");
        }

        auto oldNode = backNode;
        backNode = backNode->prev;

        if (backNode != nullptr) {
            backNode->next = nullptr;
        } else {
            // Deque is empty
            frontNode = nullptr;
        }

        auto oldValue = oldNode->value;
        delete oldNode;
        _size--;
        return oldValue;
    }
};

struct Elem {
    size_t index;
    int value;
};

int main() {
    std::ifstream ifs("deque.in");
    std::ofstream ofs("deque.out");

    Deque<Elem> deq;

    std::size_t N, K;
    ifs >> N >> K;

    long long sum_of_minimums = 0;
    for (std::size_t i = 0; i < N; i++) {
        int x;
        ifs >> x;

        while (!deq.empty() && x <= deq.back().value) {
            deq.pop_back();
        }
        deq.push_back({i, x});

        if (deq.front().index + K <= i) {
            deq.pop_front();
        }
        if (i + 1 >= K && !deq.empty()) {
            // Once we have read at least K numbers, start summing the minimums
            sum_of_minimums += deq.front().value;
        }
    }

    ofs << sum_of_minimums << '\n';
    return 0;
}