Pagini recente » Cod sursa (job #2507175) | Cod sursa (job #366410) | Cod sursa (job #1907381) | Cod sursa (job #1050128) | Cod sursa (job #3310749)
///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;
}