Cod sursa(job #581675)

Utilizator chibicitiberiuChibici Tiberiu chibicitiberiu Data 14 aprilie 2011 14:49:36
Problema Arbori de intervale Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 3.29 kb
#define DEBUG 0

#include <stdio.h>
#include <vector>

#if DEBUG==1
#include <iostream>
#endif
using namespace std;

// T must have the = and < operators
template <class T>
class ArboreInterval
{
    vector<T> Elem;
    int Size;

    int* _init_arr;
    void _Init(int tree_index, int l, int r)
    {
        if (Elem.size() <= tree_index) Elem.resize(tree_index+1);

        if (l != r)
        {
            _Init(tree_index*2, l, (l+r)/2 );
            _Init(tree_index*2 + 1, (l+r)/2 + 1, r);
        }
    }

    void _Init_Arr(int tree_index, int l, int r)
    {
        if (Elem.size() <= tree_index) Elem.resize(tree_index+1);

        if (l != r)
        {
            _Init_Arr(tree_index*2, l, (l+r)/2 );
            _Init_Arr(tree_index*2 + 1, (l+r)/2 + 1, r);

            Elem[tree_index] = (Elem[2*tree_index] < Elem[2*tree_index + 1]) ?
                Elem[2*tree_index + 1] : Elem[2*tree_index] ;
        }

        else {
            Elem[tree_index] = _init_arr[l];
        }
    }

    int _modify_index; T _modify_newVal;
    void _Modify (int index, int l, int r)
    {
        if (l != r)
        {
            int m = l+(r-l)/2;

            if (_modify_index > m) _Modify (2*index + 1, m+1, r);
            else _Modify (2*index, l, m);

            Elem[index] = (Elem[2*index] < Elem[2*index + 1]) ? Elem[2*index + 1] : Elem[2*index] ;
        }

        else {
            Elem[index] = _modify_newVal;
        }
    }


    T _Max (int index, int sl, int sr, int l, int r)
    {
        if ((sl == l && sr == r) || l==r) return Elem[index];

        int ml = max(sl, l);
        int mr = min(sr, r);

        int mid = l + (r-l)/2;

        // Go only left
        if (mr <= mid) return _Max(2*index, ml, mr, l, mid);
        // Only right
        else if (ml > mid) return _Max(2*index + 1, ml, mr, mid+1, r);
        // Both
        else {
            T a = _Max(2*index, ml, mr, l, mid);
            T b = _Max(2*index + 1, ml, mr, mid+1, r);
            return (a<b) ? b : a;
        };
    }

public:
    ArboreInterval() { }
    ArboreInterval(int size) { Initialize(size); }
    ArboreInterval(int arr[], int size) { Initialize(arr, size); }

    void Initialize(int size)
    {
        Size = size;
        _Init(1,1,size);
    }

    void Initialize(int arr[], int size)
    {
        Size = size;
        _init_arr = arr;
        _Init_Arr(1,1,size);
    }

    void ModifyValue (int index, T newVal)
    {
        _modify_index = index; _modify_newVal = newVal;
        _Modify(1,1,Size);
    }

    T GetMax (int left, int right)
    {
        return _Max(1, left, right, 1, Size);
    }

#if DEBUG==1
    void __Display()
    {
        cout<<"Items: ";
        for (int i=1; i<Elem.size(); i++)
            cout<<Elem[i]<<" ";
    }
#endif

};



int main()
{
    freopen ("arbint.in", "r", stdin);
#if DEBUG==0
    freopen ("arbint.out", "w", stdout);
#endif

    ArboreInterval<int> arb;
    int* Arr;

    int N, M, x, y, op;
    scanf("%d %d", &N, &M);

    
    Arr = new int[N+1];

    for (int i=1; i<=N; i++)
        scanf("%d", &Arr[i]);

    arb.Initialize(Arr, N);

#if DEBUG==1
    arb.__Display(); printf("\n");
#endif

    for (; M>0; M--)
    {
        scanf("%d %d %d", &op, &x, &y);
        if (op == 0) printf("%d\n", arb.GetMax(x,y));
        else arb.ModifyValue(x,y);
    }

    delete[] Arr;
    return 0;
}