Cod sursa(job #3331947)

Utilizator cristi_macoveiMacovei Cristian cristi_macovei Data 2 ianuarie 2026 00:03:55
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.76 kb
// if this gets accepted i'm drinking tonight
#define use_fast_io (std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cout.tie(nullptr);)
#define file_io(s) freopen(((std::string)s + ".in").c_str(), "r", stdin); freopen(((std::string)s + ".out").c_str(), "w", stdout)

#define all(a) (a.begin(), a.end())
#define range(a,i,j) (a.begin() + (i), a.begin() + (j))

#define aall(a, n) ((a, a + 1))
#define arange(a,i,j) ((a + (i), a + (j)))

const int NMAX = 1e5 + 8;

#include <iostream>
using namespace std;

template<typename tp>
class seg_tree {
private:
	int n;
	tp data[NMAX * 4];

	//! -------- replace these ---------
	static const tp __zero = -1;
	tp __merge(const tp& i, const tp& j) {
		return max(i, j);
	}
	//! --------------------------------

	void __init(int node, int left, int right, tp *a) {
		if (left == right) {
			data[node] = a[left];
			return;
		}

		int mid         = (left + right) / 2;
		int left_child  = 2 * node;
		int right_child = 2 * node + 1;

		__init(left_child, left, mid, a);
		__init(right_child, mid + 1, right, a);

		data[node] = __merge(data[left_child], data[right_child]);
	}

	tp __range_query(int node, int left, int right, int q_left, int q_right) {
		if (q_left <= left && right <= q_right) {
			return data[node];
		}

		int mid         = (left + right) / 2;
		int left_child  = 2 * node;
		int right_child = 2 * node + 1;
		tp ans = __zero;

		if (q_left <= mid)
			ans = __merge(ans, __range_query(left_child, left, mid, q_left, q_right));
		if (mid + 1 <= q_right)
			ans = __merge(ans, __range_query(right_child, mid + 1, right, q_left, q_right));

		return ans;
	}

	void __point_update(int node, int left, int right, int index, const tp& val) {
		if (left == right) {
			data[node] = val;
			return;
		}

		int mid         = (left + right) / 2;
		int left_child  = 2 * node;
		int right_child = 2 * node + 1;

		if (index <= mid)
			__point_update(left_child, left, mid, index, val);
		else
			__point_update(right_child, mid + 1, right, index, val);

		data[node] = __merge(data[left_child], data[right_child]);
	}

public:
	seg_tree() = default;

	void init(int n, tp *a) {
		this->n = n;

		__init(1, 1, n, a);
	}

	tp point_query(int index) {
		return __range_query(1, 1, n, index, index);
	}

	tp range_query(int left, int right) {
		return __range_query(1, 1, n, left, right);
	}
	
	void update(int index, const tp& value) {
		__point_update(1, 1, n, index, value);
	}
};

int n, m;
int a[NMAX];

seg_tree<int> st_max;

int main() {
	file_io("arbint");

	cin >> n >> m;

	for (int i = 1; i <= n; ++i) {
		cin >> a[i];
	}

	st_max.init(n, a);

	for (int i = 1; i <= m; ++i) {
		int op, a, b;

		cin >> op >> a >> b;

		if (op == 1) {
			st_max.update(a, b);
		}
		else {
			cout << st_max.range_query(a, b) << '\n';
		}
	}

	return 0;
}

// Made in Romania