Cod sursa(job #1507684)

Utilizator Andreiii500Andrei Puiu Andreiii500 Data 21 octombrie 2015 20:19:19
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.76 kb
#include <iostream>
#include <fstream>
using namespace std;

#define DIM 100005

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

int t[DIM*2];
int n,m,optiune;

void construieste_arbore()
{
    for(int i = n - 1; i >= 1 ; --i) /// n-1 noduri pot avea n fii.
        t[i] = max(t[i<<1], t[i<<1|1]);
}

int interogare(int st, int dr)
{
    int rasp = 0;
    st += n-1;
    dr += n-1;
    //cout<<"st="<<st<<"    dr="<<dr<<"\n";

    if(st==dr) return t[st]; /// Intersectia intr-un punct

    while(st < dr) /// Daca sunt egale, deja am verificat (st/dr anteriori). Daca s-au "depasit" (st > dr), inseamna ca s-a epuizat intervalul.
        {
            //if(st % 2 != 0) rasp = maxim(rasp, t[st++] );
            //if(dr % 2 != 0) rasp = maxim(rasp, t[--dr] );
            rasp = max(rasp, t[st]); /// Interoghez nodul 'st' (unele valori se vor repeta din fiul 'st' anterior)
            rasp = max(rasp, t[dr]); /// Interoghez nodul 'dr' (unele valori se vor repeta din fiul 'dr' anterior)

            //cout<<"st="<<st<<"    dr="<<dr<<"    rasp="<<rasp<<"\n";cout<<"t[st]="<<t[st]<<"    t[dr]="<<t[dr]<<"\n\n";

            if(st%2 == 1) st += 1; /// Daca sunt "in colt", ma mut pe tatal celui din dreapta
            if(dr%2 == 0) dr -= 1; /// Daca sunt "in colt", ma mut pe tatal celui din stanga

            st = (st>>1); /// Urc la tatal 'st'
            dr = (dr>>1); /// Urc la tatal 'dr'

            //cout<<"st="<<st<<"    dr="<<dr<<"    rasp="<<rasp<<"\n";
        }
    if(st==dr) rasp = max(rasp, t[st]);
    return rasp;
}


void afiseaza_t(int n)
{
    int i;
    cout << endl << "     Vectorul t este: ";
    for(i = 1; i < n; ++i)  /// [1, n-1] = noduri tata
        cout << t[i] << " ";
    cout << endl;
    cout << "Intersectii [frunze]: ";
    for(i = n; i < 2*n; ++i) /// [n, n*2) = noduri frunza
        cout << t[i] << " ";
    cout << endl << endl;
}

void modifica(int x, int val)
{
    int poz,vecin;

    poz = x+n-1;

    t[poz] = val;
    while(poz > 1) /// Reactualizez parintii
    {
        if(poz%2 == 1) vecin = poz-1;
        else vecin = poz+1;

        t[poz >> 1] = max(t[poz], t[vecin]);
        poz = poz >> 1;
    }

    //afiseaza_t(n);
}

int main()
{
    int i,x,a,b;

    in>>n>>m;
    for(i=1; i<=n; ++i)
    {
        in>>x;
        t[n-1+i] = x;
    }

    //cout << "Dupa citire:"; afiseaza_t(n);

    construieste_arbore();

    //cout << "\nDupa constructie:"; afiseaza_t(n);

    for(i=1; i<=m; ++i)
    {
        in>>optiune>>a>>b;

        if(optiune == 0) out<<interogare(a,b)<<"\n";
            //cout << "In intervalul [" << a << ", " << b << "]  nr maxim este: " << interogare(a, b) << endl;
        else modifica(a, b);
    }


    return 0;
}