Cod sursa(job #3298831)

Utilizator sonia.peiovPeiov Sonia sonia.peiov Data 2 iunie 2025 14:39:23
Problema Arbori de intervale Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.49 kb
// https://infoarena.ro/problema/arbint

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

using namespace std;

// 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, unsigned int* tree) {
	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, tree);
		}
		else {
			// Actualizam subarborele drept
			Update(2 * node + 1, mid + 1, end, idx, value, tree);
		}
		// 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]
void Query(unsigned int node, unsigned int start, unsigned int end, unsigned int l, unsigned int r, unsigned int* tree, unsigned int& result) {
	if (l > end || r < start) {
		// Intervalul curent nu se intersecteaza cu [l, r]
		return;
	}
	if (l <= start && end <= r) {
		// Intervalul curent este inclus in [l, r]
		result = max(result, tree[node]);
		return;
	}
	unsigned int mid = (start + end) / 2;
	Query(2 * node, start, mid, l, r, tree, result);
	Query(2 * node + 1, mid + 1, end, l, r, tree, result);
}

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;
	assert(M >= 1 && N <= 100000);

	vector<unsigned int> tree(4 * N, 0); // Arborele de intervale pentru maxim

	for (unsigned int i = 0; i < N; i++) {
		unsigned int a;
		fin >> a;
		assert(a <= 1000000000);

		Update(1, 1, N, i + 1, a, tree.data()); // Actualizam arborele de intervale
	}

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

		if (op == 0) {
			assert(a >= 1 && b <= N && a <= b);

			unsigned int result = 0; // Variabila pentru a stoca maximul
			Query(1, 1, N, a, b, tree.data(), result);

			fout << result << endl; // Afisam maximul pentru intervalul [a, b]
		}
		else {
			assert(op == 1 && a >= 1 && a <= N && b >= 1 && b <= 1000000000);
			
			// Actualizam valoarea elementului de pe pozitia a
			Update(1, 1, N, a, b, tree.data());
		}
	}
	
	fin.close();
	fout.close();

	return 0;
}