Cod sursa(job #3299708)

Utilizator sonia.peiovPeiov Sonia sonia.peiov Data 9 iunie 2025 15:47:25
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.96 kb
// https://infoarena.ro/problema/arbint

#include <iostream>
#include <fstream>
#include <assert.h>
#include <algorithm>
#include <vector>

using namespace std;

unsigned int* tree;

// Functia construieste arborele de intervale
void Build(unsigned int node, unsigned int start, unsigned int end, const vector<unsigned int>& A) {
	if (start == end) {
		// Frunza: stocheaza valoarea elementului original
		tree[node] = A[start];
	}
	else {
		unsigned int mid = (start + end) / 2;
		Build(2 * node, start, mid, A);          // Construieste subarborele stang
		Build(2 * node + 1, mid + 1, end, A);    // Construieste subarborele drept
		tree[node] = max(tree[2 * node], tree[2 * node + 1]); // Combina rezultatele
	}
}

// Functia actualizeaza valoarea unui element in arborele de intervale
void Update(unsigned int node, unsigned int start, unsigned int end, unsigned int idx, unsigned int value) {
	if (start == end) {
		// Am ajuns la frunza
		tree[node] = value;
	}
	else {
		unsigned int mid = (start + end) / 2;
		if (idx <= mid) {
			// Actualizam subarborele stang
			Update(2 * node, start, mid, idx, value);
		}
		else {
			// Actualizam subarborele drept
			Update(2 * node + 1, mid + 1, end, idx, value);
		}
		// Recalculam valoarea maxima pentru nodul curent
		tree[node] = max(tree[2 * node], tree[2 * node + 1]);
	}
}

// Functia interogheaza arborele de intervale pentru a gasi maximul in intervalul [l, r]
unsigned int Query(unsigned int node, unsigned int start, unsigned int end, unsigned int l, unsigned int r) {
	// Intervalul curent nu se intersecteaza cu [l, r]
	if (r < start || end < l) {
		return 0; // Returneaza o valoare care nu va afecta maximul
	}
	// Intervalul curent este inclus in [l, r]
	if (l <= start && end <= r) {
		return tree[node];
	}
	// Intervalul se intersecteaza partial, interogam subarborii
	unsigned int mid = (start + end) / 2;
	unsigned int p1 = Query(2 * node, start, mid, l, r);
	unsigned int p2 = Query(2 * node + 1, mid + 1, end, l, r);
	return max(p1, p2);
}

int main() {
	ifstream fin("arbint.in");
	ofstream fout("arbint.out");
	if (!fin.is_open() || !fout.is_open()) {
		cerr << "Eroare la deschiderea fisierelor!" << endl;
		return 1;
	}

	unsigned int M, N;
	fin >> N >> M;

	tree = new unsigned int[4 * N + 1]; // Alocam memorie pentru arborele de intervale

	vector<unsigned int> A(N + 1); // Vector pentru a stoca valorile initiale
	for (unsigned int i = 1; i <= N; ++i) {
		fin >> A[i];
	}

	// Construim arborele de intervale cu valorile initiale
	Build(1, 1, N, A);

	for (unsigned int i = 0; i < M; ++i) {
		unsigned int op, a, b;
		fin >> op >> a >> b;

		if (op == 0) {
			// Interogare pentru maxim
			fout << Query(1, 1, N, a, b) << endl;
		}
		else {
			// Actualizare a valorii
			Update(1, 1, N, a, b);
		}
	}

	// Eliberam memoria alocata pentru arborele de intervale
	delete[] tree;
	tree = nullptr;
	
	fin.close();
	fout.close();

	return 0;
}