Cod sursa(job #2187846)

Utilizator alexandru223Dan Alexandru Dicu alexandru223 Data 26 martie 2018 19:35:20
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.53 kb
#include <bits/stdc++.h>
using namespace std;
#define REP(i, a, b) for (int i = a; i < b; i++)
#define TRvi(c, it) for (vi::iterator it = c.begin(); it != c.end(); it++)
#define TRvii(c, it) for (vii::iterator it = c.begin(); it != c.end(); it++)
#define INF 2000000000

typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pii> vii;

#define MAXVAL 100005

int arr[MAXVAL];
vi segment_tree;

void initialise_segment_tree(int arr_size) {
	segment_tree.resize(int(2*pow(2.0, floor(log(double(arr_size))/log(2.0))+1)), -1);
}
void build_segment_tree(int node, int left, int right) {
	if (left == right) segment_tree[node] = left;
	else {
		int left_id = 2*node, right_id = 2*node+1;
		build_segment_tree(left_id, left, (left+right)/2);
		build_segment_tree(right_id, (left+right)/2+1, right);
		int left_cont = segment_tree[left_id];
		int right_cont = segment_tree[right_id];
		int left_val = arr[left_cont];
		int right_val = arr[right_cont];
		segment_tree[node] = (left_val > right_val)? left_cont : right_cont;
	}
}
void update_segment_tree(int node, int left, int right, int pos) {
	if (left == right) {
		segment_tree[node] = left;
		return;
	}
	int mid = (left+right)/2;
	if (pos <= mid) update_segment_tree(2*node, left, mid, pos);
	else update_segment_tree(2*node+1, mid+1, right, pos);
	segment_tree[node] = ((arr[segment_tree[2*node]] > arr[segment_tree[2*node+1]])? segment_tree[2*node] : segment_tree[2*node+1]);
}
int solve_query(int node, int q_l, int q_r, int left, int right) {
	if (q_l > right || q_r < left) return -1;
	if (left >= q_l && right <= q_r) return segment_tree[node];
	int p1 = solve_query(2*node, q_l, q_r, left, (left+right)/2);
	int p2 = solve_query(2*node+1, q_l, q_r, (left+right)/2+1, right);
	if (p1 == -1) return p2;
	if (p2 == -1) return p1;
	return (arr[p1] > arr[p2])? p1 : p2;
}
void print_segment_tree() {
	int k = 1;
	for (int it : segment_tree) {
		if (it == -1) continue;
		cout << it;
		k++;
		if (floor(log(k)/log(2)) == log(k)/log(2)) cout << '\n';
	}
}
int main() {
	freopen("arbint.in", "r", stdin);
	freopen("arbint.out", "w", stdout);
	int n, n_queries;
	scanf("%d%d", &n, &n_queries);
	REP(i, 0, n) scanf("%d", &arr[i]);
	initialise_segment_tree(n);
	build_segment_tree(1, 0, n-1);
	REP(i, 0, n_queries) {
		int type, left, right;
		scanf("%d%d%d", &type, &left, &right);
		if (!type) printf("%d\n", arr[solve_query(1, left-1, right-1, 0, n-1)]);
		else {
			arr[left-1] = right;
			update_segment_tree(1, 0, n-1, left-1);
		}
	}
	return 0;
}