Cod sursa(job #1743923)

Utilizator sulzandreiandrei sulzandrei Data 18 august 2016 22:42:27
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.15 kb
#include <iostream>
#include <algorithm>
#include <fstream>
using namespace std;
#define sizez 100004
ifstream in("arbint.in");
ofstream out("arbint.out");
int A[sizez],a,b,m,n,tip;
void bruteForce()
{
    int j = 1;
    in >> n >> m;
    while(n--)
        in >> A[j++];
    while(m--)
    {
        in >> tip  >> a >> b;
        if(tip)
            A[a] = b;
        else
            out << *max_element(A+a,A+b+1,[](int a, int b){return a<b;}) << '\n';
    }
}
int Max[sizez],St[sizez],Dr[sizez];//Max[i] inseamna maximul din al i interval de dimensiune radical(n)
//St[i] reprezinta pozitia din vectorul A unde incepe updatarea maximuli pentru al i-lea interval de dimensiune sqrt(n)
//Dr[i] reprezinta pozitia din A unde se termina updatarea maximului pentru al i interval
int size = 0;
void Update();
int Query();
void smenuLuiBatog()
{

    in >> n >> m;
    for(int i = 1 ; i <= n ; i ++)
    {
        in >> A[i];
        if( size*size<=n)
            size++;
    }
    size--;//dimensiunea unui interval si numarul de intervale
    for(int i = 1 ; i *size <= n ; i++)//pentru fiecare interval de dimensiune size
    {
        Max[i] = -1;//presupun ca maximul este -1
        St[i] = size*(i-1)+1; Dr[i] = size*i;//updatam St[i] si Dr[i]
        for(int pos = St[i] ; pos <= Dr[i]; pos++)//updatam Max[i] verificam pentru toate pozitiile din vectorul A
            Max[i] = max(Max[i],A[pos]);// care reprezinta al i interval de dimensiune size
    }
    while(m--)
    {
        in >> tip >> a >> b;
        if(tip)
            Update();
        else
            out << Query() <<'\n';
    }
}
void Update()//cazul cand modificam o singura valorea
{
    A[a] = b;
    for(int i = 1 ; i*size <= n ; i++)//updatam si vectorul Max
        if(St[i]<= a && a <= Dr[i])//verificand in al catelea interval este valoarea a
        {
            Max[i] = -1;
            for(int pos = St[i] ; pos <=Dr[i] ; pos++)
                Max[i] = max(Max[i],A[pos]);
            break;//si cazul cand nu este in niciun interval nu e problema pt ca e tratat mai jos
        }
}
int Query()
{
    int valmaxim = -1;//valoarea maxima din intervalul a-b
    //distingem 3 cazuri
    //cazul 1 - cand a si b reprezinta capul si coada exacte ale unuor intervale
    bool caz2 = true, caz3 = true;
    int capata, inceputb;
    for(int i = 1 ; i*size <= n ; i++)
    {
        if(a <= St[i] && Dr[i] <= b)
            valmaxim = max(valmaxim,Max[i]);
        if(a == St[i])
            caz2 = false;
        if(b == Dr[i])
            caz3 = false;
        if(a >= St[i] && a <=Dr[i])
            capata = Dr[i];
        if(b >= St[i] && b <=Dr[i])
            inceputb = St[i];
    }
    if(size*size < b)
        inceputb = size*size + 1;
    //cazul 2- cand a nu reprezinta capul sunui interval de dimensiunea radical(n)(size)
    if(caz2)
        for(int i = a ; i <= min(capata,b) ; i++)
            valmaxim = max(valmaxim,A[i]);
    if(caz3)
        for(int i = max(inceputb,a); i<= b;  i++)
            valmaxim = max(valmaxim,A[i]);
    return valmaxim;
}
int main()
{
    //bruteForce();
    smenuLuiBatog();
    return 0;
}