Cod sursa(job #2934353)

Utilizator TudosieRazvanTudosie Marius-Razvan TudosieRazvan Data 5 noiembrie 2022 21:18:08
Problema Arbori de intervale Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.86 kb
#include <fstream>
#include <climits>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <bitset>
#include <map>
#include <cstring>
#include <algorithm>
#define NMAX 100003

using namespace std;

//Solutia cu Smenul lui Batog
//50 puncte

int n,k,nrB;
int v[NMAX];

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

struct bucket {
	int st, dr;
	int maxim;
}buckets[NMAX/2];


int query(int st, int dr)
{
	//caut binar care e bucket-ul care il contine pe st
	int a = 1, b = nrB,indice=-1;
	while (a <= b)
	{
		int mij = (a + b) / 2;
		if (buckets[mij].st <= st)
		{
			indice = mij;
			b = mij - 1;
		}
		else {
			a = mij + 1;
		}
	}

	int maxim = -1;
	//in solSt am indicele bucket-ului
	for (int i = st; i <= buckets[indice].dr; i++)
	{
		maxim = max(v[i], maxim);
	}

	indice++;
	while (indice <= nrB && buckets[indice].dr <= dr)
	{
		maxim = max(maxim, buckets[indice].maxim);//maximul din bucket-urile intermediare
		indice++;
	}

	//maximul din ultimul bucket partial
	for (int i = buckets[indice].st; i <= dr && indice <= nrB; i++)
	{
		maxim = max(v[i], maxim);
	}
	return maxim;
}

void update(int poz, int x)
{
	//caut binar care e bucket-ul care il contine pe poz
	int st = 1, dr = nrB, indice = -1;
	while (st <= dr)
	{
		int mij = (st + dr) / 2;
		if (buckets[mij].st <= poz && poz <= buckets[mij].dr)
		{
			indice = mij;
			break;
		}
		else if (poz > buckets[mij].dr)
		{
			st = mij + 1;
		}
		else {
			dr = mij - 1;
		}
	}

	//reactualizez bucket-ul indice
	v[poz] = x;
	buckets[indice].maxim = -1;
	for (int i = buckets[indice].st; i <= buckets[indice].dr; i++)
	{
		buckets[indice].maxim = max(buckets[indice].maxim, v[i]);
	}
}

int main()
{
	

	fin >> n>>k;
	for (int i = 1; i <= n; i++)
	{
		fin >> v[i];
	}
	

	int lg = sqrt(n);//o sa am lg elemente in fiecare bucket
	
	nrB = n / lg;//numarul de bucket-uri
	for (int i = 1; i <= nrB; i++)
	{
		buckets[i].st = buckets[i - 1].st + 1;
		buckets[i].dr = i*lg;
		//imi iau maximul pe secventa
		buckets[i].maxim = -1;
		for (int j = buckets[i].st; j <= buckets[i].dr; j++)
		{
			buckets[i].maxim = max(buckets[i].maxim, v[j]);
		}
	}
	//e posibil sa imi mai ramana elemente
	if (n % lg != 0)
	{
		nrB++;
		buckets[nrB].st = buckets[nrB - 1].dr + 1;
		buckets[nrB].dr = n;
		buckets[nrB].maxim = -1;
		for (int j = buckets[nrB].st; j <= buckets[nrB].dr; j++)
		{
			buckets[nrB].maxim = max(buckets[nrB].maxim, v[j]);
		}
	}



	for (int i = 1; i <= k; i++)
	{
		int cerinta;
		fin >> cerinta;
		if (cerinta == 0)
		{
			//se va face query 
			int indSt, indDr;
			
			fin >> indSt >> indDr;
			
			fout << query(indSt, indDr) << "\n";
		}
		else {
			//se face update
			int poz,val;
			fin >> poz>>val;
			update(poz,val);
		}
	}
	return 0;
}