Cod sursa(job #3172396)

Utilizator redstonegamer22Andrei Ion redstonegamer22 Data 20 noiembrie 2023 16:19:21
Problema Deque Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.89 kb
#include <bits/stdc++.h>

using namespace std;

const int nmax = 5 * 1e6 + 7;
int v[nmax];

struct MinStacks {
	stack<pair<int, int>> dreapta, stanga;

	// fiecare stack retine perechi de forma <element, minimul elementelor care sunt in stiva in acel moment mai jos>
	// dreapta este stiva pe care _intra_ elemente in structura
	// stanga este folosita atunci cand elementele ies

	void add_element(int index) {
		if(dreapta.size() == 0) {
			dreapta.push({v[index], v[index]});
		} else {
			dreapta.push({v[index], min(v[index], dreapta.top().second)});
		}
	}

	int get_min() {
		if(dreapta.size() == 0 && stanga.size() == 0) return -1;
		if(dreapta.size() == 0) {
			return stanga.top().second;
		}
		if(stanga.size() == 0) {
			return dreapta.top().second;
		}

		return min(dreapta.top().second, stanga.top().second);
	}

	void remove_element() {
		// incercam sa dam pop la un element din stanga

		if(stanga.size() > 0) {
			stanga.pop();
			return;
		}

		// daca nu avem elemente in stanga, avem o problema
		// De unde le luam? Din dreapta!

		while(dreapta.size() > 0) {
			int x = dreapta.top().first; dreapta.pop();
			if(stanga.size() == 0) {
				stanga.push({x, x});
			} else {
				stanga.push({x, min(x, stanga.top().second)});
			}
		}

		// acum ca am luat elemente din dreapta, doar dam pop la unul

		stanga.pop();
	}
};

#ifndef LOCAL
ifstream in("deque.in");
ofstream out("deque.out");
#define cin in
#define cout out
#endif

int main() {
	int n, k; cin >> n >> k;

	for(int i = 1; i <= n; i++) cin >> v[i];

	// Varianta finala: Folosim un deque pentru a retine minimul pe fiecare interval de lungime k
	// Folosim un deque pentru a retine minimul pe fiecare interval de lungime k

	MinStacks md;
	for(int i = 1; i <= k; i++) {
		md.add_element(i);
	}

	long long ans = md.get_min();

	for(int i = k + 1; i <= n; i++) {
		md.add_element(i);
		md.remove_element();

		ans += md.get_min();
	}

	cout << ans << "\n";
}