Cod sursa(job #406424)

Utilizator cipriancxFMI - gr143 Timofte Ciprian cipriancx Data 1 martie 2010 15:22:57
Problema Arbori de intervale Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.46 kb
#include <iostream>

using namespace std;



struct arbore{
    int st;
    int dr;
    long max;
};

arbore v[300001];

long vec[100001];



void creaza(int nod, int a, int b)
{

int mij=(a+b)/2;

v[nod].st=a; v[nod].dr=b;
v[nod].max=-1;

if(a!=b)
{
creaza(2*nod,a,mij);
creaza(2*nod+1,mij+1,b);

}


}
//functia creaza arborele binar; e facuta bine


void actualizare(int nod, int poz,long valoare)
{
    if(v[nod].st<=poz && poz<=v[nod].dr)
    {

    if(v[nod].max<=valoare)v[nod].max=valoare;

    if(v[nod].st!=v[nod].dr)
    {
    actualizare(2*nod,poz,valoare);
    actualizare(2*nod+1,poz,valoare);

    }
    }



}

//actualizarea introduce primele noduri in arbore. functia merge



long interogare(int nod,int a,int b)
{
    if(a<=v[nod].st && v[nod].dr<=b) return v[nod].max;
    else
    {
        long fiust=0,fiudr=0;
    int mij=(v[nod].st+v[nod].dr)/2;
     if(v[nod].st!=v[nod].dr)
     {

     if(a<=mij)fiust=interogare(2*nod,a,b);
     if(b>mij) fiudr=interogare(2*nod+1,a,b);
     }

     if(fiust>fiudr)return fiust; else return fiudr;
    }

return 0;


}

//functia interogare returneaza valoarea maxima dintr-un interval; functia merge

int search(int nod,int valoare)
{
    if(v[nod].st==valoare && v[nod].dr==valoare)return nod;
    else{

     int mij=(v[nod].st+v[nod].dr)/2;
     if(v[nod].st<=valoare && valoare<=mij)return search(2*nod,valoare);
     else return search(2*nod+1,valoare);
    }

}

//functia search returneaza nodul frunza in care e valoare respectiva.


void update(int nod)
{
    if(nod!=1)
    {
      if(nod%2==0)
      {
        if(v[nod].max>v[nod+1].max)v[nod/2].max=v[nod].max;
        else v[nod/2].max=v[nod].max;



       }
       else
       {
       if(v[nod].max>v[nod-1].max)v[nod/2].max=v[nod].max;
       else v[nod/2].max=v[nod-1].max;


       }

       update(nod/2);


    }

}
//inainte de a face apel nodul trebuie updatat



int n,m,i;

int main()
{


    freopen("arbint.in","r",stdin);
    freopen("arbint.out","w",stdout);
    int n;

 cin>>n>>m;
 //creem arborele de intervale
creaza(1,1,n);



for(i=1; i<=n; i++)
{
    cin>>vec[i];
    actualizare(1,i,vec[i]);
}
for(i=1; i<=m; i++)
{
 int a,b,c;

cin>>a>>b>>c;
if(a==0)cout<<interogare(1,b,c)<<'\n';
else
{
   int nn=search(1,b);
   v[nn].max=c;
   update(nn);

}





}











    return 0;
}