Cod sursa(job #3299563)

Utilizator vladm98Munteanu Vlad vladm98 Data 8 iunie 2025 15:11:59
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.17 kb
#include <bits/stdc++.h>

using namespace std;

int generateRandomNumber() {
	return abs((1LL * rand() << 15) + rand()) % 1000000000 + 1; // 1 ... 1e9
}

struct TreapNode {
	int position, value, priority;
	TreapNode *left, *right;

	int minPosition, maxPosition, maxValue;

	TreapNode(TreapNode *l, TreapNode *r, int pos, int val, int pr, int minPos, int maxPos) {
		left = l;
		right = r;
		position = pos;
		value = val;
		priority = pr;
		minPosition = minPos;
		maxPosition = maxPos;
		maxValue = value;
	}
};
TreapNode *NILL = new TreapNode(nullptr, nullptr, -1, -1e9, -1, 1e9, -1e9);

void leftRotate(TreapNode *& node) {
	TreapNode *aux = node->right;
	node->right = aux->left;
	aux->left = node;
	node = aux;
}

void rightRotate(TreapNode *& node) {
	TreapNode *aux = node->left;
	node->left = aux->right;
	aux->right = node;
	node = aux;
}

void recheck(TreapNode *& node) {
	if (node == NILL) return;
	node->maxValue = node->value;
	node->maxValue = max(node->maxValue, node->left->maxValue);
	node->maxValue = max(node->maxValue, node->right->maxValue);

	node->minPosition = min(node->position, node->left->minPosition);
	node->maxPosition = max(node->position, node->right->maxPosition);
}

void balance(TreapNode *& node) {
	if (node == NILL) return;
	if (node->priority < node->left->priority) {
		rightRotate(node);
	}
	if (node->priority < node->right->priority) {
		leftRotate(node);
	}
	recheck(node->left);
	recheck(node->right);
	recheck(node);
}

void insert(TreapNode *& node, int pos, int val) {
	if (node == NILL) {
		node = new TreapNode(NILL, NILL, pos, val, generateRandomNumber(), pos, pos);
		return;
	}
	if (pos < node->position) {
		insert(node->left, pos, val);
	} else {
		insert(node->right, pos, val);
	}
	balance(node);
}

int maximumQuery(TreapNode *& node, int left, int right) {
	if (node == NILL) return -1e9;

	int maxLeft = -1e9;
	int maxRight = -1e9;
	int maxCurrent = -1e9;

	if (left <= node->minPosition and node->maxPosition <= right) return node->maxValue;

	if (left <= node->position and node->position <= right) maxCurrent = node->value;
	if (left <= node->left->maxPosition) {
		maxLeft = maximumQuery(node->left, left, right);
	}
	if (node->right->minPosition <= right) {
		maxRight = maximumQuery(node->right, left, right);
	}

	return max(maxCurrent, max(maxLeft, maxRight));
}

void erase(TreapNode *& node, int pos) {
	if (node == NILL) return;
	if (pos < node->position) {
		erase(node->left, pos);
	} else if (pos > node->position) {
		erase(node->right, pos);
	} else {
		if (node->left == NILL and node->right == NILL) {
			delete node;
			node = NILL;
		} else if (node->left->position < node->right->position) {
			leftRotate(node);
			erase(node, pos);
		} else {
			rightRotate(node);
			erase(node, pos);
		}
	}
	balance(node);
}

int main(){
	freopen("arbint.in", "r", stdin);
	freopen("arbint.out", "w", stdout);
	srand(6565);
	TreapNode *root = NILL;

	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; ++i) {
		int val;
		cin >> val;
		insert(root, i, val);
	}
	for (int i = 1; i <= m; ++i) {
		int type, x, y;
		cin >> type >> x >> y;

		if (type == 0) {
			cout << maximumQuery(root, x, y) << '\n';
		} else {
			erase(root, x);
			insert(root, x, y);
		}
	}
	return 0;
}