Cod sursa(job #3235300)

Utilizator daristyleBejan Darius-Ramon daristyle Data 16 iunie 2024 20:45:21
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.48 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>
#include <string>
#include <algorithm>
#include <set>
#include <cassert>
#include <map>
#include <iomanip>
#include <functional>
#include <bits/stdc++.h>

using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
const bool LOCAL = true;
const bool DEBUG = LOCAL & false;
const bool HAS_TESTS = false;

template<typename T>
class SegmentTree{
private:
		unsigned int size;
		vector<T> segTree;
		T identityElement;
		function<T(T, T)> merge;

		void computeChildren(int node, int left, int right, int& middle, int& leftChild, int& rightChild){
			middle = (left + right) / 2;
			leftChild = node + 1;
			rightChild = leftChild + 2 * (middle - left + 1) - 1;
		}

		void build(int node, int left, int right, const vector<T>& v){
			if(left == right){
				segTree[node] = v[left];
			}else{
				int middle, leftChild, rightChild;
				computeChildren(node, left, right, middle, leftChild, rightChild);

				build(leftChild, left, middle, v);
				build(rightChild, middle + 1, right, v);

				segTree[node] = merge(segTree[leftChild], segTree[rightChild]);
			}
		}

		void update(int node, int left, int right, int pos, T val){
			if(left == right){
				segTree[node] = val;
			}else{
				int middle, leftChild, rightChild;
				computeChildren(node, left, right, middle, leftChild, rightChild);

				if(pos <= middle)
					update(leftChild, left, middle, pos, val);
				else
					update(rightChild, middle + 1, right, pos, val);

				segTree[node] = merge(segTree[leftChild], segTree[rightChild]);
			}
		}

		T query(int node, int left, int right, int qleft, int qright){
			T retval = identityElement;
			if(qleft <= left && right <= qright)
				retval = segTree[node];
			else{
				int middle, leftChild, rightChild;
				computeChildren(node, left, right, middle, leftChild, rightChild);

				if(qleft <= middle)
					retval = query(leftChild, left, middle, qleft, qright);
				if(middle + 1 <= qright)
					retval = merge(retval, query(rightChild, middle + 1, right, qleft, qright));
			}

			return retval;
		}

public:

		SegmentTree() : size(0), identityElement(T()), merge(nullptr){}

		void resize(int _size){
			size = _size;
			segTree.resize(2 * size - 1, identityElement);
		}

		void init(int _size, function<T(T, T)> _merge, T _identityElement, vector<T> v){
			merge = _merge;
			identityElement = _identityElement;
			resize(_size);
			build(0, 0, size - 1, v);
		}

		SegmentTree(int _size, function<T(T, T)> _merge, T _identityElement, vector<T> v){
			init(_size, _merge, _identityElement, v);
		}

		void update(int pos, T val){
			update(0, 0, size - 1, pos, val);
		}

		T query(int qleft, int qright){
			return query(0, 0, size - 1, qleft, qright);
		}

};

const int UPDATE = 1;
const int QUERY = 0;

int mx(int a, int b){
	return (a > b) ? a : b;
}


void Solve(istream& in, ostream& out){
	int n, m;
	n = m = 5;
	in >> n >> m;
	vector<int> v(n);
	for(auto& x: v)
		in >> x;

	SegmentTree<int> segtree(n, mx, -1, v);

	int op, a, b;
	for(int i = 0; i < m; ++i){
		in >> op >> a >> b;
		if(op == UPDATE)
			segtree.update(a - 1, b);
		else
			out << segtree.query(a - 1, b - 1) << '\n';
	}

}

signed main(){
	if(LOCAL){
		int tests;
		if(HAS_TESTS)
			fin >> tests;
		else
			tests = 1;

		for(int test = 0; test < tests; ++test){
			Solve(fin, fout);
		}
	}else{
		int tests;
		if(HAS_TESTS)
			cin >> tests;
		else
			tests = 1;

		for(int test = 0; test < tests; ++test){
			Solve(cin, cout);
		}
	}

	fin.close();
	fout.close();
	return 0;
}