Cod sursa(job #1310953)

Utilizator tweetyMarinescu Ion tweety Data 7 ianuarie 2015 15:31:15
Problema Deque Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 8.82 kb
#include <cstdio>
#include <deque>

#define LIM_MAX 5000000
using namespace std;

template <typename T>
class Node
{
public:
    /** CONSTRUCTOR/DESTRUCTOR METHODS **/

    //ctor - initializes data and next pointer
    Node(const T& data) : m_data(data), m_next(NULL)
    {

    }

    //dtor - unlinks this node from his next one
    virtual ~Node()
    {
        unlink();
    }

    /** GET METHODS **/

    //returns the T data of this node
    T getData() const
    {
        return m_data;
    }

    //returns pointer to the next node
    virtual Node<T>* getNext() const
    {
        return m_next;
    }

    /** SET METHODS **/

    //change the T data of this node
    void setData(const T& data)
    {
        m_data = data;
    }

    /** LINK/UNLINK METHODS **/

    //sets the next node
    void linkTo(Node<T>* nextNode)
    {
        m_next = nextNode;
    }

    //unlinks this node by linking it to null
    void unlink()
    {
        linkTo(NULL);
    }

protected:
    //data of this current node
    T m_data;
    //pointer to next node
    Node<T>* m_next;
};

template<typename T>
class SimpleList
{
public:
    /** CONSTRUCTOR/DESTRUCTOR METHODS **/

    //ctor - simple initialization
    SimpleList() : m_head(NULL), m_tail(NULL), m_size(0)
    {

    }

    //dtor - removes every node
    virtual ~SimpleList()
    {
        removeAll();
        m_head = NULL;
        m_tail = NULL;
    }

    /** GET METHODS **/

    //returns pointer to head of the list
    virtual Node<T>* getHead() const
    {
        return m_head;
    }

    //returns pointer to end of the list
    virtual Node<T>* getTail() const
    {
        return m_tail;
    }

    //returns size of the list
    int getSize() const
    {
        return m_size;
    }

    /** BOOL METHODS **/

    //tests if the list is empty
    bool isEmpty() const
    {
        return getSize() == 0;
    }

    //checks if an element is found inside the list
    bool isInside(const T& data) const
    {
        return searchElement(data) != NULL;
    }

    /** REMOVE ELEMENT METHODS **/

    //removes the first node which contains specified info
    bool removeElement(const T& data)
    {
        return removeNode(searchElement(data));
    }

    //removes the nod (argument) node
    bool removeElement(Node<T>* nod)
    {
        return removeNode(nod);
    }

    //removes every node which contains the data (argument)
    bool removeAllOccurences(const T& data)
    {
        Node<T>* temp;
        while ((temp = searchElement(data)))
            if (!removeNode(temp))
                return false;

        return true;
    }

    //removes all nodes from the list
    bool removeAll()
    {
        while (!isEmpty())
            if (!removeNode(getHead()))
                return false;

        return true;
    }

    /** ADD ELEMENT METHODS **/

    //push a new element at the end of the list
    void push_back(const T& data)
    {
        addNodeToTail(new Node<T>(data));
    }

    //create a new node at the beginning
    void push_front(const T& data)
    {
        addNodeToHead(new Node<T>(data));
    }

protected:
    //head pointer
    Node<T>* m_head;
    //tail pointers
    Node<T>* m_tail;
    //# of nodes inside the list
    int m_size;

    /** SET METHODS **/

    //set head pointer to new one
    void setHead(Node<T>* newhead)
    {
        m_head = newhead;
    }

    //set tail pointer to new one and unlink it from anything else
    void setTail(Node<T>* newtail)
    {
        newtail->unlink();
        m_tail = newtail;
    }

    /** REMOVE NODE METHODS **/

    //removes a node
    bool removeNode(Node<T>* current)
    {
        if (isEmpty() || !current)
            return false;

        if (current == getHead())
        {
            setHead(current->getNext());
            current->unlink();
            delete current;

            --m_size;
            return true;
        }

        Node<T>* temp = getHead();
        while (temp && temp->getNext() != current)
                temp = temp->getNext();

        if (!temp)
            return false;

        if (current != getTail())
        {
            Node<T>* ptr = temp->getNext();

            temp->linkTo(ptr->getNext());
            ptr->unlink();
            delete ptr;

            --m_size;
            return true;
         }

         Node<T>* next = temp->getNext();
         setTail(temp);
         delete next;

         --m_size;
         return true;
    }

    /** ADD NODES METHODS **/

    //add a node after the tail
    void addNodeToTail(Node<T>* nod)
    {
        if (!nod)
            return;

        if (isEmpty())
        {
            ++m_size;
            setHead(nod);
            setTail(nod);

            return;
        }

        ++m_size;
        getTail()->linkTo(nod);
        setTail(nod);
    }

    //add a node before the head
    void addNodeToHead(Node<T>* nod)
    {
        if (!nod)
            return;

        if (isEmpty())
        {
            ++m_size;
            setHead(nod);
            setTail(nod);

            return;
        }

        ++m_size;
        nod->linkTo(getHead());
        setHead(nod);
    }

    /** SEARCH & EXTRA METHODS **/

    //returns pointer to first occurence of an element (or null)
    Node<T>* searchElement(const T& data) const
    {
        Node<T>* temp = getHead();
        while (temp && temp->getData() != data)
            temp = temp->getNext();

        return temp;
    }
};

template<typename T>
class Queue
{
public:
    /** CONSTRUCTOR/DESTRUCTOR METHODS **/

    //ctor - creates new underlying container of type SimpleList
    Queue()
    {
        m_list = new SimpleList<T>();
    }

    //dtor - deallocates the memory required for the underlying container
    virtual ~Queue()
    {
        delete m_list;
    }

    /** BOOL METHODS **/

    //checks if the list is empty
    bool isEmpty() const
    {
        return m_list->isEmpty();
    }

    /** GET METHODS **/

    //returns size of the list
    int getSize()
    {
        return m_list->getSize();
    }

    //returns the first element in the list (from the head)
    T front()
    {
        if (isEmpty())
            return false;

        return m_list->getHead()->getData();
    }

    //adds a new element at the end of the list (at the tail)
    void enqueue(const T& element)
    {
        m_list->push_back(element);
    }

    //removes the first element (the head)
    bool dequeue()
    {
        return m_list->removeElement(m_list->getHead());
    }

protected:
    //pointer to a SimpleList used as the underlaying data structure for the Queue
    SimpleList<T>* m_list;
};

template<typename T>
class Deque : public Queue<T>
{
public:
    /** CONSTRUCTOR/DESTRUCTOR METHODS **/

    //ctor - creates new underlying container of type SimpleList
    Deque()
    {
        this->m_list = new SimpleList<T>();
    }

    //dtor - does nothing, prevents compiler from generating default dtor
    ~Deque()
    {

    }

    /** PUSH BACK/FRONT METHODS **/

    //adds the element at the end of the deque
    void push_back(const T& element)
    {
        this->enqueue(element);
    }

    //adds an element at the beginning of the deque
    void push_front(const T& element)
    {
        this->m_list->push_front(element);
    }

    /** POP BACK/FRONT METHODS **/

    //removes the last element of the deque
    void pop_back()
    {
        this->m_list->removeElement(this->m_list->getTail());
    }

    //removes the first element of the deque
    void pop_front()
    {
        this->dequeue();
    }

    /** GET METHODS **/

    //returns the last element, front method is implemented in parent class
    T back()
    {
        if (this->isEmpty())
            return false;

        return this->m_list->getTail()->getData();
    }
};

int myArray[LIM_MAX];

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

    long long int i;
    long long int N;
    long long int K;
    long long int S = 0;
    Deque<long long int> myDeque;

    scanf("%lld %lld", &N, &K);
    for (i = 1; i <= N; ++i)
        scanf("%lld", &myArray[i]);
    fclose(in);

    for (i = 1; i <= N; ++i)
    {
        while (!myDeque.isEmpty() && myArray[myDeque.back()] >= myArray[i])
            myDeque.pop_back();

        myDeque.push_back(i);

        if (myDeque.front() == i - K)
            myDeque.pop_front();

        if (i >= K)
            S += myArray[myDeque.front()];
    }

    printf("%lld", S);
    fclose(out);

    return 0;
}