Cod sursa(job #1734401)

Utilizator alexnekiNechifor Alexandru alexneki Data 27 iulie 2016 11:35:42
Problema Arbori de intervale Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 3.23 kb
#include <cstdio>
#include <cassert>
#include <algorithm>
#include <iostream>

struct ArbInt {
	int size;
	int max;
	ArbInt *left;
	ArbInt *right;
};

ArbInt* emptyArb = nullptr;

ArbInt* addNode(ArbInt* arbInt, int add) {
	return new ArbInt{
		arbInt->size,
		arbInt->max,
		arbInt->left, arbInt->right};
//  *arbInt = ArbInt{
//    arbInt->size,
//    arbInt->max,
//    arbInt->left, arbInt->right};
//  return arbInt;
}

ArbInt* join(ArbInt* left, ArbInt* right) {
	return new ArbInt{
		left->size + right->size,
		std::max(left->max, right->max),
		left, right};
}

ArbInt* morpheNode(ArbInt* arbInt, ArbInt* left, ArbInt* right) {
	return new ArbInt{
		left->size + right->size,
		std::max(left->max, right->max),
		left, right};
	//*arbInt = ArbInt{
	//  left->size + right->size,
	//  std::max(left->max, right->max),
	//  left, right};
	//return arbInt;
}

//arbInt has empty sons
ArbInt* morpheNode(ArbInt* arbInt, int value) {
	return new ArbInt{
		arbInt->size,
		value,
		arbInt->left, arbInt->right};
	//*arbInt = ArbInt{
	//  arbInt->size,
	//  arbInt->max + value,
	//  arbInt->left, arbInt->right};
	//return arbInt;
}

ArbInt* build(int* begin, int* end) {
	int size = end - begin;
	assert(0 < size);

	if (size == 1)
		return new ArbInt{size, *begin, emptyArb, emptyArb};
	else {
		int half = size / 2;
		ArbInt* arbLeft = build(begin, begin + half);
		ArbInt* arbRight = build(begin + half, end);
		return join(arbLeft, arbRight);
	}
}

ArbInt* update(ArbInt* arbInt, int i, int value) {
	assert(arbInt != emptyArb && 0 <= i && i < arbInt->size);

	if (arbInt->size == 1)
		return morpheNode(arbInt, value);
	else if (i < arbInt->left->size)
		return morpheNode(arbInt,
						  update(arbInt->left, i, value),
						  arbInt->right);
	else
		return morpheNode(arbInt,
						  arbInt->left,
						  update(arbInt->right, i - arbInt->left->size, value));
}

ArbInt* query(ArbInt* arbInt, int from, int to) {
//	printf("%d %d %d\n", arbInt->size, from, to);
//	fflush(stdout);
	assert(arbInt != emptyArb && 0 <= from && from <= to && to < arbInt->size);

	if (from == 0 && to == arbInt->size - 1)
		return arbInt;
	else if (to < arbInt->left->size)
		return query(arbInt->left, from, to);
	else if (arbInt->left->size <= from)
		return query(arbInt->right, from - arbInt->left->size, to - arbInt->left->size);
	else
		return join(
			query(arbInt->left, from, arbInt->left->size - 1),
			query(arbInt->right, 0, to - arbInt->left->size));
}

void dump(ArbInt* arbInt, int depth = 0) {
	if (arbInt != emptyArb) {
		dump(arbInt->left, depth + 1);
		for (int i = 0; i < depth; i++) {
			printf("  ");
		}
		printf("%1d %2d\n", arbInt->size, arbInt->max);
		dump(arbInt->right, depth + 1);
	}
}

int main() {
	freopen("arbint.in", "r", stdin);
	freopen("arbint.out", "w", stdout);
	int N, M;
	scanf("%d%d", &N, &M);
	int* V = new int[N];
	for (int i = 0; i < N; i++)
		scanf("%d", &V[i]);
	// fa ceva cu V
	ArbInt* arbInt = build(V, V + N);
//	dump(arbInt, 0);
//	std::cout<<std::endl;
	for (int i = 0; i < M; i++) {
		int op, a, b;
		scanf("%d%d%d", &op, &a, &b);
		if (op == 0) { // query
			int answer = query(arbInt, a - 1, b - 1)->max;
			printf("%d\n", answer);
		} else { // update
			arbInt = update(arbInt, a - 1, b);
//			dump(arbInt, 0);
//			std::cout<<std::endl;
		}
	}
	return 0;
}