Cod sursa(job #759402)
#include<fstream>
#define max(a,b) (a < b ? b : a)
#define nmax 100105
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int N, arbint[4 * nmax + 66], val , poz, M, maxi = -1;//memoria alocata este de: N +N/2 + N/4+ N/8
int start, finish ; //pt interogari
void query(int nod, int st, int dr)
{
if(start <= st && dr <= finish)//daca intervalul actual(st,dr) este inclus in intervalul dorit(strat,finish) putem sa actualizam maximul, cu cel din interval daca e cazul. Acesta fiind sigur in intervalul cautat
{
if(maxi < arbint[nod])
maxi = arbint[nod];
return;
}
int mij = (st + dr)/2;
if(mij >= start)//daca intervalul (st, mij) intersectat cu intervlul(start, finish) != NULL => ar puteaz exista un maxim in acet interval
query(nod+ nod, st, mij);
if(mij < finish)//-||-(mij + 1, dr)
query(nod + nod + 1, mij + 1, dr);
}
void update(int nod, int st, int dr)
{
if(st == dr)
{
arbint[nod] = val;
return;
}
int mij = (st + dr) /2;
if(mij >= poz)//actualizez doar in intervalele care il contin pe poz
update(nod + nod, st, mij);
else
update(nod + nod + 1, mij + 1, dr);
arbint[nod] = max(arbint[nod + nod] , arbint[nod + nod + 1]);//actualizez maximul intervalelor dupa ce am schimbat elementul de pe poz
}
void read()
{
fin >>N >>M;
for(int i = 1; i <= N;i++){
fin>> val; poz = i ;
update(1, 1, N);
}
for(int i = 1; i <= M;i++)
{
int tip ;
fin >> tip >>poz>> val;
maxi = -1;
if(tip == 1)
update(1, 1, N);
else
{
start = poz;
finish = val;
maxi = -1;
query(1, 1, N);
fout << maxi <<'\n';
}
}
}
int main()
{
read();
fin.close();
return 0;
}