Cod sursa(job #3143559)

Utilizator daristyleBejan Darius-Ramon daristyle Data 31 iulie 2023 12:50:03
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.58 kb
#include <fstream>

using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");

const int N_MAX = 1e5;
const int SQRT_N = 317;

int v[N_MAX], sqrtdecomp[SQRT_N];

void build(int v[], int n){
	int sqrt_i = 0, mx = v[0];
	for(int i = 1; i < n; ++i){
		if(i >= (sqrt_i + 1) * SQRT_N){
			sqrtdecomp[sqrt_i++] = mx;
			mx = v[i];
		}else if(mx < v[i])
			mx = v[i];
	}
	sqrtdecomp[sqrt_i] = mx;
}

void update(int pos, int value){
	int interval = pos / SQRT_N;
	if(sqrtdecomp[interval] <= value){
		sqrtdecomp[interval] = value;
		v[pos] = value;
	}else if(sqrtdecomp[interval] == v[pos]){
		v[pos] = value;
		int begin = interval * SQRT_N;
		int end = begin + SQRT_N;
		sqrtdecomp[interval] = v[begin];
		for(int i = begin + 1; i < end; ++i)
			if(sqrtdecomp[interval] < v[i])
				sqrtdecomp[interval] = v[i];
	}else
		v[pos] = value;
}

int query(int begin, int end){
	int begin_interval = (begin + SQRT_N - 1) / SQRT_N;
	int end_interval = end / SQRT_N;
	int mx = v[begin];

	for(int i = begin + 1; i < min(begin_interval * SQRT_N, end); ++i)
		if(mx < v[i])
			mx = v[i];

	for(int i = begin_interval; i < end_interval; ++i)
		if(mx < sqrtdecomp[i])
			mx = sqrtdecomp[i];

	for(int i = max(end_interval * SQRT_N, begin + 1); i <= end; ++i)
		if(mx < v[i])
			mx = v[i];

	return mx;
}

int main(){
	int n, queries;
	fin >> n >> queries;

	for(int i = 0; i < n; ++i)
		fin >> v[i];

	build(v, n);

	for(int i = 0; i < queries; ++i){
		int type, a, b;
		fin >> type >> a >> b;
		if(type)
			update(a - 1, b);
		else
			fout << query(a - 1, b - 1) << '\n';
	}

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