Cod sursa(job #2730168)

Utilizator ReksioCroftOctavian Florin Staicu ReksioCroft Data 25 martie 2021 21:13:40
Problema Deque Scor 100
Compilator cpp-32 Status done
Runda Arhiva educationala Marime 5.16 kb
#include <fstream>
#include <cstdio>
#include <cassert>
#include <cctype>

class inputParser {

    static const unsigned int buffSize = 1 << 17;

    unsigned int pozBuff;

    FILE* fin;

    unsigned char* buffer;



    void getChar( unsigned char& ch ) {

        if ( pozBuff == buffSize ) {

            pozBuff = 0;

            assert( fread( buffer, sizeof( char ), buffSize, fin ) );

        }

        ch = buffer[ pozBuff++ ];

    }



public:

    explicit inputParser( const char* fileName ) {

        fin = fopen( fileName, "r" );

        assert( fin != nullptr );

        buffer = new unsigned char[buffSize];

        pozBuff = buffSize;

    }



    inputParser( const inputParser& dummy ) = delete;



    inputParser& operator=( const inputParser& dummy ) = delete;



    template < class intType >

    inputParser& operator>>( intType& nr ) {

        int sgn( 1 );

        unsigned char ch;

        nr = 0;

        getChar( ch );

        while ( isdigit( ch ) == 0 && ch != '-' )

            getChar( ch );

        if ( ch == '-' ) {

            sgn = -1;

            getChar( ch );

        }

        while ( isdigit( ch ) != 0 ) {

            nr = nr * 10 + ch - '0';

            getChar( ch );

        }

        nr *= sgn;

        return *this;

    }



    inputParser& operator>>( char& ch ) {

        unsigned char ch2;

        do {

            getChar( ch2 );

        } while ( isgraph( ch2 ) == 0 );

        ch = static_cast<char>(ch2);

        return *this;

    }



    inputParser& operator>>( unsigned char& ch ) {

        getChar( ch );

        do {

            getChar( ch );

        } while ( isgraph( ch ) == 0 );

        return *this;

    }



    ~inputParser() {

        fclose( fin );

        delete[] buffer;

    }

};

class MyNode {
private:
    const int val, ind;
    MyNode* next;

public:
    MyNode( int val, int ind );

    int getVal() const;

    int getInd() const;

    MyNode* getNext() const;

    void setNext( MyNode* );

    ~MyNode();

};

MyNode::~MyNode() {
    next = nullptr;
}

void MyNode::setNext( MyNode* nxt ) {
    next = nxt;
}

MyNode* MyNode::getNext() const {
    return next;
}

int MyNode::getVal() const {
    return val;
}

int MyNode::getInd() const {
    return ind;
}

MyNode::MyNode( int val, int ind ) : val( val ), ind( ind ) {
    next = nullptr;
}

class MyDeque {
    MyNode* fst;
    MyNode* beforeLast;

public:

    MyDeque();

    void popFront();

    void pushBack( MyNode* );

    void popBack( int );

    MyNode* getFst() const;

    MyNode* getLast() const;

    ~MyDeque();
};

MyDeque::MyDeque() {
    fst = beforeLast = nullptr;
}

MyDeque::~MyDeque() {
    while ( fst != nullptr )
        popFront();
}

MyNode* MyDeque::getFst() const {
    return fst;
}

MyNode* MyDeque::getLast() const {
    if ( beforeLast != nullptr && beforeLast->getNext() != nullptr )
        return beforeLast->getNext();
    else
        return beforeLast;
}

void MyDeque::popBack( int nr ) {
    MyNode* last = getLast();

    if ( last != nullptr && ( last->getVal() > nr ) ) {
        MyNode* node = beforeLast = fst;
        MyNode* aux;

        if ( node->getVal() < nr ) {
            while ( node->getNext() != nullptr && node->getNext()->getVal() < nr ) {
                beforeLast = node;
                node = node->getNext();
            }

            aux = node;
            node = node->getNext();
            aux->setNext( nullptr );

        } else {
            fst = beforeLast = nullptr;
        }
        while ( node != nullptr ) {
            aux = node;
            node = node->getNext();
            delete aux;
        }
    }
}

void MyDeque::pushBack( MyNode* myNode ) {
    if ( fst == nullptr ) {
        fst = beforeLast = myNode;
    } else {
        if ( beforeLast->getNext() != nullptr ) {
            if ( beforeLast->getNext()->getVal() == myNode->getVal() ) {
                delete beforeLast->getNext();
            } else
                beforeLast = beforeLast->getNext();
        }
        beforeLast->setNext( myNode );
    }
}

void MyDeque::popFront() {
    if ( fst != nullptr ) {
        if ( beforeLast->getNext() == nullptr ) {
            delete fst;
            fst = beforeLast = nullptr;
        } else {
            MyNode* aux = fst;
            if ( beforeLast == fst )
                fst = beforeLast = fst->getNext();
            else
                fst = fst->getNext();
            delete aux;
        }
    }
}


int main() {
    int n, k;
    long long s( 0LL );
    MyDeque myDeque;        //obs: va fi mereu sortat crescator
    inputParser fin( "deque.in" );
    fin >> n >> k;
    for ( int i = 1; i <= n; i++ ) {
        int nr;
        fin >> nr;
        myDeque.popBack( nr );

        MyNode* myDequeNode = new MyNode( nr, i );
        myDeque.pushBack( myDequeNode );

        //trb sa ne asiguram ca nu am depasit intervalul
        while ( myDeque.getFst() != nullptr && myDeque.getLast()->getInd() - myDeque.getFst()->getInd() >= k )
            myDeque.popFront();

        if ( i >= k && myDeque.getFst() != nullptr ) {
            s += myDeque.getFst()->getVal();
        }
    }

    std::ofstream fout( "deque.out" );
    fout << s << '\n';
    fout.close();

    return 0;
}