Cod sursa(job #1792363)

Utilizator dranoellenTurica Leonard-Petru dranoellen Data 30 octombrie 2016 13:21:38
Problema Arbori de intervale Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.61 kb
#include <cstdio>
#include <algorithm>

using namespace std;
int m,n;
struct arb
{
    int st,dr,mx=0;
}nod[100005];
FILE *in=fopen("arbint.in","r"),*out=fopen("arbint.out","w");

void constr(int poz, int val,int decons)
{
    if(nod[decons].st==nod[decons].dr)
    {
        nod[decons].mx=val;
        return;
    }
    nod[decons].mx=max(val,nod[decons].mx);
    int mij=(nod[decons].dr+nod[decons].st)/2;
    if(poz<=mij)
        nod[decons*2].st=nod[decons].st,
        nod[decons*2].dr=mij,
        constr(poz,val,decons*2);
    else
        nod[decons*2+1].st=mij+1,
        nod[decons*2+1].dr=nod[decons].dr,
        constr(poz,val,decons*2+1);
}

void inloc(int poz,int val, int dever)
{
    if(nod[dever].st==nod[dever].dr)
    {
        nod[dever].mx=val;
        return;
    }
    int mij=(nod[dever].dr+nod[dever].st)/2;
    if(poz<=mij)
        inloc(poz,val,dever*2),
        nod[dever].mx=max(nod[dever*2+1].mx,nod[dever*2].mx);
    else
        inloc(poz,val,dever*2+1),
        nod[dever].mx=max(nod[dever*2].mx,nod[dever*2+1].mx);

}

int maxim(int st, int dr)
{
    int poz=1,mij,ant;
    while(1)
    {
        mij=(nod[poz].st+nod[poz].dr)/2;
        if(st==nod[poz].st)
        {
            if(dr>nod[poz].dr)break;
            else if(dr==nod[poz].dr)return nod[poz].mx;
            else poz*=2;
        }
        else
        {
            if(st<=mij)
                poz=poz*2;
            else
                poz=poz*2+1;
        }
    }
    ant=poz;
    mij=nod[poz].mx;
    while(1)
    {
        if(poz%2)
        {
            ++poz;
            if(nod[poz].mx==0)poz/=2;
        }
        else
            poz/=2;

        if(nod[poz].dr>dr)
        {
            poz=ant*2+1;
            if(nod[poz].mx==0) ++poz;
                return max(mij,nod[poz].mx);
        }

        if(nod[poz].dr==dr)return max(mij,nod[poz].mx);

        if(nod[poz].dr<dr) mij=max(mij,nod[poz].mx),ant=poz;
    }


    return mij;
}
/*
void scriefrum()
{
    int i,lvl=2,k;
    for(k=1;k<n;)k*=2;
    k*=2;
    for(i=1;i<k;++i)
    {
        if(lvl==i)
            fprintf(out,"\n"),
            lvl*=2;
        fprintf(out,"% 3d ",nod[i].mx);

    }
    fprintf(out,"\n\n\n");
}
*/
int main()
{
    fscanf(in,"%d%d",&n,&m);

    nod[1].dr=n-1;
    nod[1].st=0;
    int i,a,b,cmnd;
    for(i=0;i<n;++i)
        fscanf(in,"%d",&a),
        constr(i,a,1);

    for(i=0;i<m;++i)
    {
        fscanf(in,"%d%d%d",&cmnd,&a,&b);
        if(cmnd)inloc(a-1,b,1);
        else fprintf( out,"%d\n",maxim(a-1,b-1));
    }
    return 0;
}