Cod sursa(job #2093185)

Utilizator gundorfMoldovan George gundorf Data 23 decembrie 2017 09:51:08
Problema Arbori de intervale Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.8 kb
#include <iostream>
#include <fstream>
#define Nmax 100010
#include <cmath>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int n,v[Nmax],m;
int arb[300000];
void Citire ()
{ int i;
    fin>>n>>m;
    for (i=1; i<=n; i++)
        fin>>v[i];

}
int Creare_arb (int l,int r,int nod)
{ int v1,v2;
    if (r==l) arb[nod]=v[l]; //daca sunt intr o frunza maximul pe intervalul ala e chiar elementul din vector
    else
    {
        int middle=(l+r)/2;
        Creare_arb ( l,middle,2*nod ) ; //impart intervalul in 2
        Creare_arb ( middle+1 ,r , 2*nod+1 ) ;
        arb[nod]=max(arb[2*nod],arb[2*nod+1]); //altfel, e maximul dintre cele 2 intervale de sub el
    }
}
int cautare_binara (int nod,int st,int dr,int x) // caut frunza (adica pozitia in vectorul arb ) corespunzatoare pozitiei x din vectorul inital
{

    while (st<=dr)
    { int middle=(st+dr)/2;
        if (st==dr&&st==x) return nod;

        if (middle<x) { nod = nod*2 + 1 ; st = middle + 1 ; }
        else { nod = nod*2 ; dr = middle ; }
    }

}


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

  if (poz!=1) update (poz/2);

}

int query (int nod,int l,int r,int st,int dr)
{ int v1=0,v2=0;
    if (l>=st && r<=dr)
        return arb[nod];

    if (l>dr||r<st) return 0;

    int middle=l+(r-l)/2;
    v1=query (2*nod,l,middle,st,dr);
    v2=query (2*nod+1,middle+1,r,st,dr);

    return max(v1,v2);

}


int main()
{int i,x,y,z;
    Citire();
    Creare_arb(1,n,1);
   for (i=1;i<=m;i++)
    {
        fin>>x>>y>>z;
        if (x==0) fout<<query(1,1,n,y,z)<<"\n";
        if (x==1)
        {
            v[y]=z;
            int poz=cautare_binara(1,1,n,y);
            arb[poz]=z;
            update(poz);
        }
    }


    return 0;
}