Cod sursa(job #2614527)

Utilizator MarcGrecMarc Grec MarcGrec Data 11 mai 2020 20:47:31
Problema Arbori de intervale Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.52 kb
#define MAX_N 100000
#define LOG_MAX_N 16
#define INF 0x3f3f3f3f

#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;

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

struct nodeinfo
{
	nodeinfo() :
		a(0),
		b(0),
		ma(0),
		u(0),
		v(0),
		f(0)
	{
	}
	
	int a, b, ma, u, v, f;
};

int n, m, node_val, A[MAX_N + 1], I[MAX_N + 1];
nodeinfo G[1 << (LOG_MAX_N + 2)];

void ConstructTree(int node, int a, int b);

void Set(int index, int val);

int MaxRange(int a, int b);
void Query(int node, int a, int b, int& ma);

int main()
{
	fin >> n >> m;
	for (int i = 1; i <= n; ++i)
	{
		fin >> A[i];
	}
	
	ConstructTree(++node_val, 1, n);
	
	for (int i = 0, q, a, b; i < m; ++i)
	{
		fin >> q >> a >> b;
		
		if (q == 0)
		{
			fout << MaxRange(a, b) << '\n';
		}
		else
		{
			Set(a, b);
		}
	}
	
	fin.close();
	fout.close();
	return 0;
}

void ConstructTree(int node, int a, int b)
{	
	G[node].a = a;
	G[node].b = b;
	
	if (a == b)
	{
		I[a]       = node;
		G[node].ma = A[a];
	}
	else
	{
		const int mid = (a + b) / 2;
		
		G[node].u     = ++node_val;
		G[node_val].f = node;
		ConstructTree(node_val, a, mid);
		
		G[node].v     = ++node_val;
		G[node_val].f = node;
		ConstructTree(node_val, mid + 1, b);
		
		G[node].ma = max(G[G[node].u].ma, G[G[node].v].ma);
	}
}

void Set(int index, int val)
{
	G[I[index]].ma = val;
	
	int node = G[I[index]].f, ma_old;
	while (node != 0)
	{
		ma_old     = G[node].ma;
		G[node].ma = max(G[G[node].u].ma, G[G[node].v].ma);
		node       = (G[node].ma != ma_old) ? G[node].f : 0;
	}
}

int MaxRange(int a, int b)
{	
	int ma = G[I[a]].ma;
	Query(I[a], a, b, ma);
	
	return ma;
}

bool Ok(int ap, int bp, int a, int b)
{
	return (ap >= a) && (bp <= b);
}

void Down(int node, int a, int b, int& ma)
{
	if (Ok(G[node].a, G[node].b, a, b))
	{
		ma = max(G[node].ma, ma);
	}
	
	if (G[node].b == b)
	{
		return;
	}
	
	int lf = G[node].u;
	int rg = G[node].v;
	if (G[lf].b >= b)
	{
		Down(lf, a, b, ma);	
	}
	else
	{
		if (Ok(G[lf].a, G[lf].b, a, b))
		{
			ma = max(G[lf].ma, ma);
		}
		Down(rg, a, b, ma);
	}
}

void Query(int node, int a, int b, int& ma)
{
	if (Ok(G[node].a, G[node].b, a, b))
	{
		ma = max(G[node].ma, ma);
	}
	
	if (G[node].b >= b)
	{
		Down(node, a, b, ma);
		return;
	}
	
	if (G[node].a < a)
	{
		int v = G[node].v;
		if (Ok(G[v].a, G[v].b, a, b))
		{
			ma = max(G[v].ma, ma);
		}
	}
	
	Query(G[node].f, a, b, ma);
}