Cod sursa(job #795224)

Utilizator gener.omerGener Omer gener.omer Data 7 octombrie 2012 20:46:32
Problema Arbori de intervale Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.66 kb
#include <iostream>
#include <fstream>

using namespace std;

#define NMAX 100005
#define LOGNMAX 20

int N, M, A[NMAX], T[(1 << LOGNMAX)];

int start, finish;

inline void fill(int nod, int b, int e)
{
	if(b == e)
	{
		T[nod] = b;
	}
	else
	{
		fill(2 * nod + 1, b, b + (e - b) / 2);
		fill(2 * nod + 2, b + (e - b) / 2 + 1, e);
		
		if(A[T[2 * nod + 1]] <= A[T[2 * nod + 2]])
			T[nod] = T[2 * nod + 2];
		else
			T[nod] = T[2 * nod + 1];
	}
}

void preprocess()
{
	fill(0, 0, N - 1);
}

inline int query(int nod, int b, int e)
{
	int p1, p2;
	
	if(start > e || finish < b)
	{
		return -1;
	}
	
	if(start <= b && finish >= e)
	{
		return T[nod];
	}
	
	p1 = query(2 * nod + 1, b, b + (e-b) / 2);
	p2 = query(2 * nod + 2, b + (e-b) / 2 + 1, e);
	
	if(p1 == -1)
		return p2;
	else if(p2 == -1)
		return p1;
	else
	{
		if(A[p1] < A[p2])
			return p2;
		else 
			return p1;
	}
}

inline void update(int nod, int b, int e, int pos)
{
	if(b == e)
	{
		T[nod] = b;
	}
	else
	{
		if(pos >= b && pos <= b + (e - b) / 2)
		{
			update(2 * nod + 1, b, b + (e - b) / 2, pos);
		}
		else
		{
			update(2 * nod + 2, b + (e - b) / 2 + 1, e, pos);
		}
		
		if(A[T[2 * nod + 1]] <= A[T[2 * nod + 2]])
			T[nod] = T[2 * nod + 2];
		else
			T[nod] = T[2 * nod + 1];
	}
}

int main()
{
	freopen("arbint.in", "rt", stdin);
	freopen("arbint.out", "wt", stdout);

	scanf("%d %d", &N, &M);
	for(int i = 0; i < N; ++i)
		scanf("%d", &A[i]);
	
	preprocess();
	for(int i = 0; i < M; ++i)
	{
		int cod, a, b;
		scanf("%d %d %d", &cod, &a, &b);
		if(cod == 0)
		{
			start = a - 1;
			finish = b - 1;
			printf("%d\n", A[query(0, 0, N - 1)]);
		}
		else
		{
			A[a - 1] = b;
			update(0, 0, N - 1, a - 1);
		}
	}
	return 0;
}