Cod sursa(job #2730093)

Utilizator ReksioCroftOctavian Florin Staicu ReksioCroft Data 25 martie 2021 19:17:11
Problema Deque Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 6.03 kb
#include <cstdio>
#include <cassert>
#include <cctype>
#include <fstream>

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 MyDequeNode {
private:
    const int val, ind;
    MyDequeNode* next;
public:
    MyDequeNode( int val, int ind );

    int getVal() const;

    int getInd() const;

    MyDequeNode* getNext() const;

    void setNext( MyDequeNode* );

    ~MyDequeNode();

};

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

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

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

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

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

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

class MyDeque {
    MyDequeNode* fst;
    MyDequeNode* beforeLast;
    int co;
public:

    MyDeque();

    void popFront();

    void pushBack( MyDequeNode* );

    void popBack( int );

    MyDequeNode* getFst() const;

    MyDequeNode* getLast() const;

    ~MyDeque();
};

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

void MyDeque::popBack( int nr ) {
    MyDequeNode* last = ( beforeLast != nullptr ) ? ( ( beforeLast->getNext() != nullptr ) ? beforeLast->getNext()
                                                                                           : beforeLast ) : nullptr;
    if ( last != nullptr && ( last->getVal() > nr ) ) {// || ( last->getVal() == nr && co > 3600000 ) ) ) {
        MyDequeNode* node = beforeLast = fst;
        MyDequeNode* aux;
        while ( node->getNext() != nullptr && node->getNext()->getVal() < nr ) {
            if ( node->getVal() == node->getNext()->getVal() ) {
                aux = node->getNext();
                node->setNext( aux->getNext() );
                delete aux;
                co--;
            }
            if ( node->getNext() != nullptr && node->getNext()->getVal() < nr ) {
                beforeLast = node;
                node = node->getNext();
            }
        }

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

        while ( node != nullptr ) {
            aux = node;
            node = node->getNext();
            delete aux;
            co--;
        }

        if ( fst->getVal() >= nr ) {
            delete fst;
            fst = beforeLast = nullptr;
            co = 0;
        }
    }
}

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

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

MyDequeNode* MyDeque::getLast() const {
    MyDequeNode* last = ( beforeLast != nullptr ) ? ( ( beforeLast->getNext() != nullptr ) ? beforeLast->getNext()
                                                                                           : beforeLast ) : nullptr;
    return last;
}


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

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


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

        MyDequeNode* myDequeNode = new MyDequeNode( 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();
        }
    }

    FILE* fout = fopen( "deque.out", "w" );
    fprintf( fout, "%lld\n", s );
    fclose( fout );

    return 0;
}