Cod sursa(job #2811679)

Utilizator nushLaura Maria nush Data 2 decembrie 2021 20:58:29
Problema Deque Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4 kb
#include <iostream>
#include <fstream>
using namespace std;
ifstream f("deque.in");
ofstream g("deque.out");
int a[5000010];
struct Deque
{
    long long x; // last
    long long y; // first
    long long dim;
    long long index;
    long long deq[5000010];
};
void push(int e, Deque &d)
{
    d.dim++;
    d.deq[d.index + d.dim - 1] = e;
}
void poplast(Deque &d)
{
    if(d.dim>0)
    {
        d.dim--;
    }
}
void popfirst(Deque &d)
{
    if(d.dim > 0)
    {
        d.dim--;
        d.index++;
    }
}
int getFirst(Deque& d) {                        // AICI AM PUS FUNCTIILE ASTEA CARE SA ITI DEA PRIMUL SI ULTIMUL, CA TE AMETEAI DACA LE CALCULAI
    return d.deq[d.index];                      // TOT IN POP/PUSH
}                                               // FUNCTIILE ASTEA SUNT CORECTE DOAR DACA STIVA NU E GOALA
int getLast(Deque& d){
    return d.deq[d.index + d.dim - 1];
}
int isEmpty(Deque& d){
    if(d.dim == 0){
        return true;
    }
    return false;
}


Deque stivadubla;
long long n,k,s;

void info(){
    cout<<"\nStiva contine:\n";
    for(int i = 0 ; i < stivadubla.index + stivadubla.dim + 10; i++){
        cout<< a[stivadubla.deq[i]] << " ";
    }
    cout<<"\n index = " << stivadubla.index << " dimensiune = "<< stivadubla.dim << " x = last = " << a[stivadubla.x] << " y = first =" << a[stivadubla.y] << "\n";
    for(int i = stivadubla.index ; i < stivadubla.index + stivadubla.dim; i++){
        cout<< a[stivadubla.deq[i]] << " ";
    }
    cout <<"\n";
}

int main()
{
    stivadubla.y=0;
    stivadubla.x=0;
    stivadubla.dim=0;
    stivadubla.index=0;
    f>>n>>k;
    for(int i=0;i<n;i++)
        f>>a[i];
    push(0,stivadubla);             // ACUM CA NU MAI DAI POP CU STIVA GOALA, POTI SA INCEPI FOR-UL de la 0, sa nu mai dai push aici

    // cele 3 componente sunt asa:
    // - adaugare nomala in deque: se face la fecare pas
    // - expirarea unui element din deque: cand deque.first == index - k
    // - gasirea minimului pe o subsecventa de k: se face la fiecare pas, odata ce index >= k-1
    for(int i = 1; i < n; i++)
    {
        if(isEmpty(stivadubla)==true || a[i]>a[getLast(stivadubla)])
        {
            push(i,stivadubla);
        }
        else
        {
            while(!isEmpty(stivadubla) && a[getLast(stivadubla)]>a[i])      //TU DADEAI POP SI DACA STIVA ERA GOALA
            {
                poplast(stivadubla);
            }
            push(i,stivadubla);
        }
        if(!isEmpty(stivadubla) && getFirst(stivadubla) + k == i)          //expirarea // SI AICI LA FEL< PUTEA FI STIVA GOALA
        {
            popfirst(stivadubla);
        }
        if(i >= k - 1)                                              // SI AICI MINUMUL SE CALCULEAZA DOAR DUPA CE TREC k ELEMENTE
        {
            s += a[getFirst(stivadubla)];
        }
    }
    g<<s;


    return 0;

}

/*
Solutia1
parcurg lista de la 1 la n cu un iterator i si apoi in el
parcurg cu un iterator j de la i la k+i si retin min pe secventa parcursa de j
*/
///complexitate: n*k;
/*
Solutia2
Not cu x=ultimul elem din deque la fiecare pas
Not cu y=primul elem din deque la fiecare pas
parcurgem sirul cu un iterator i:
-si testam daca ultimul element din deque este mai mic decat a[i] adica: a[x] < a[i]?
-daca este, il bagam pe i in deque la sfarsit (ca sa tinem minte pozitia): a[x] < a[i]
-daca nu este, -il pop pe ultimul element din deque cat timp este mai mic decat a[i] (a[x]<a[i])
               -il bagam pe i in deque
-cand head-ul din deque plus k este egal cu i, atunci il pop pe head;
*/
///complexitate: n
///pt ca la fiecare pas cand pop uieste elem dinainte ptc sunt mai mari, nu are cum sa pop uiasca k elemente la fiecare element bagat
///de ex daca k=6 are a b c d e si vrea sa il bage pe f (toate sunt mai mari si le da pop) dupa in deque o sa il aiba doar pe f si nu o sa mai aiba cum sa
///pop uiasca tot k-1 elemente ca e doar f acolo therefore nu are cum sa fie complexitatea n*(k-1)