Cod sursa(job #287920)

Utilizator whiskeyOzzy Osbourne whiskey Data 25 martie 2009 12:33:01
Problema Arbori de intervale Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.9 kb
#include <stdio.h>
#include <vector>
#include <iostream>
using namespace std;

int n, m, maxpoz = 0;
vector<int> arb;
vector<int> pozitii;

void solve();
void build(int, int, int);
void update(int);
int query(int, int);
inline int max(int, int);

int main()
{
	solve();
	return 0;
}

void solve()
{
	int i, x, y, z;
	FILE *fin = fopen("arbint.in", "r");
	FILE *fout = fopen("arbint.out", "w");
	fscanf (fin, "%d%d", &n, &m);
	arb.resize(4 * n + 200);
	pozitii.resize(n + 1);
	build(1, n, 1);
	for (i = 1; i <= n; ++i)
	{
		fscanf(fin, "%d", &arb[pozitii[i]]);
		update(pozitii[i]);
	}
	for (i = 1; i <= m; ++i)
	{
		fscanf(fin, "%d%d%d", &x, &y, &z);
		if (x == 1)
		{
			arb[pozitii[y]] = z;
			update(pozitii[y]);
		}
		else
		{
			fprintf (fout, "%d\n", query(pozitii[y], pozitii[z]));
		}
	}
	fclose(fin);
	fclose(fout);
}

int query(int poz1, int poz2)
{
	int max1 = arb[poz1], max2 = arb[poz2];
/*	for (int i = 1; i <= maxpoz; ++i)
	{
		printf ("%d ", arb[i]);
	}
	printf ("\nAflu maximul cuprins intre %d si %d:\n", arb[poz1], arb[poz2]);
*/	while (poz1 / 2 != poz2 / 2)
	{
//		printf ("poz1: %d si poz2: %d\tmax1: %d si max2: %d\n", poz1, poz2, max1, max2);
		if (poz1 > poz2)
		{
			if (poz1 % 2)
			{
				poz1 /= 2;
			}
			else
			{
				max1 = max(arb[poz1], arb[poz1+1]);
				poz1 /= 2;
			}
		}
		else
		{
			if (poz2 % 2 == 0)
			{
				poz2 /= 2;
			}
			else
			{
				max2 = max(arb[poz2-1], arb[poz2]);
				poz2 /= 2;
			}
		}
	}
//	printf ("poz1: %d si poz2: %d\tmax1: %d si max2: %d\n\n", poz1, poz2, max1, max2);
	return max(max1, max2);
}

void build(int st, int dr, int poz)
{
	if (poz > maxpoz) maxpoz = poz;
	if (st == dr)
	{
		pozitii[st] = poz;
		return;
	}
	
	int mid = (st + dr) / 2;
	build(st, mid, poz * 2);
	build(mid + 1, dr, poz * 2 + 1);
}

void update(int poz)
{
	int t;
	for (t = poz / 2; t; t /= 2)
	{
		arb[t] = max (arb[t*2], arb[t*2+1]);
	}
}

inline int max(int x, int y)
{
	return (x > y ? x : y);
}