Cod sursa(job #3310749)

Utilizator RaresHonourRares Herinean RaresHonour Data 16 septembrie 2025 16:28:21
Problema Deque Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.98 kb
///https://www.infoarena.ro/problema/deque
/*
    Deque
    Se da un sir A cu N numere intregi. Pentru fiecare subsecventa de lungime K sa se determine minimul, iar apoi sa se calculeze suma acestor minime.

    Cerinta
    Sa se afiseze suma ceruta.

    Date de intrare
    Pe prima linie a fisierului deque.in se afla numerele N si K cu semnificatia din enunt. Pe urmatoarele N linii se afla cate un numar intreg din sirul dat.

    Date de ieşire
    In fisierul de iesire deque.out se va afla un singur numar intreg reprezentand suma ceruta.

    Restrictii si precizari
    1 ≤ N ≤ 5 000 000
    1 ≤ K ≤ N
    Elementele din sir vor avea valori cuprinse intre -10 000 000 si 10 000 000
    Pentru rezultat se recomanda folosirea tipurilor intregi pe 64 de biti

    Exemplu
    deque.in	deque.out
    9 3           -2
    -7
    9
    2
    4
    -1
    5
    6
    7
    1

    Explicaţie
    Minimele corespunzatoare fiecarei subsecvente de lungime 3 sunt: -7 2 -1 -1 -1 5 1, suma acestora fiind -2.



    Un deque este un container (o structură de date) din STL care ne permite să facem operații pe un vector în timp constant (O (1), foarte rapid).

    dacă avem un deque numit dq atunci putem face următoarele operații :
    dq.push_front (x); /// se adaugă elementul x la începutul dequelui.
    dq.pop_front (); /// se elimină primul element din deque.
    dq.push_back (x); /// se adaugă elementul x la sfârșitul dequelui.
    dq.pop_back (); /// se elimină ultimul element din deque.

    dq.back (); /// se apelează ultimul element din deque.
    dq.front (); /// se apelează primul element din deque.
    dq.empty (); /// o funcție care returnează true dacă deque-ul este gol altfel false

    Notă: pentru implementarea dequelui de mână se va folosi un vector circular, ținând la fiecare pas minte capătul stânga L și capătul dreapta R. În implementare, vom folosi STL și NU vom implementa de mână.

 */
#include <fstream>
#include <deque> //libraria pentru a folosi deque (double ended queue)

using namespace std;

ifstream cin("deque.in");
ofstream cout("deque.out");

const int nmax = 5e6;

typedef long long ll;
int v[nmax + 1];

int main() {
    int n, k, i;
    ll sum = 0;
    deque<int> dq; // !!!
    cin >> n >> k;
    for (i = 1; i <= n; i++) {
        cin >> v[i];
    }
    for (i = 1; i <= n; i++) {
        // cat timp deque ul NU e gol si ultimul element are valoare >= cu elementul curent
        // il eliminam pentru a pastra valori crescatoare in deque
        while (!dq.empty() and v[i] <= v[dq.back()]) {
            dq.pop_back(); // eliminam elementele mai mari sau egale cu cel curent
        }
        dq.push_back(i); // adaugam pozitia curenta in deque
        // daca primul element a iesit din fereastra (de lungime k) il eliminam
        if (dq.front() == i - k)
            dq.pop_front();
        // de la pasul k in sus front ul contine minimul ferestrei curente
        if (i >= k)
            sum += v[dq.front()];
    }
    cout << sum;
    return 0;
}