Cod sursa(job #1234147)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 26 septembrie 2014 20:00:28
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 4.35 kb
#include <bits/stdc++.h>

using namespace std;

class Treap
{
    typedef struct _Node
    {
        int key;
        int maxim;
        int contor;
        int priority;
        _Node *l, *r;

        _Node( const int _key, const int _priority, const int _nr_nodes, _Node *_st, _Node *_dr )
        {
            key = _key;
            maxim = _key;
            priority = _priority;
            contor = _nr_nodes;
            l = _st;
            r = _dr;
        }

        void update()
        {
            this->maxim = this->key;
            maxim = max( this->maxim, this->l->maxim );
            maxim = max( this->maxim, this->r->maxim );

            this->contor = 1;
            this->contor += this->l->contor;
            this->contor += this->r->contor;
        }

    } *Node;

    void rotateRight( Node &T )
    {
        Node aux = T->l;
        T->l = aux->r;
        aux->r = T;

        T->update();
        aux->update();

        T = aux;
    }

    void rotateLeft( Node &T )
    {
        Node aux = T->r;
        T->r = aux->l;
        aux->l = T;

        T->update();
        aux->update();

        T = aux;
    }

    void balance( Node &T )
    {
        if ( T->l->priority > T->priority )
            rotateRight( T );

        if ( T->r->priority > T->priority )
            rotateLeft( T );

        T->update();
    }

    void insert( Node &T, int pos, int key, int p = rand() % INF )
    {
        if ( T == NIL )
        {
            T = new _Node( key, p, 1, NIL, NIL );
        }
        else
        {
            if ( pos <= T->l->contor + 1 )
                insert( T->l, pos, key, p );
            else
                insert( T->r, pos - T->l->contor - 1, key, p );

            balance( T );
        }

        if ( T != NIL )
            T->update();
    }

    void erase( Node &T, int pos )
    {
        if ( T == NIL ) return;

        if ( pos <= T->l->contor )
            erase( T->l, pos );
        else
            if ( pos > T->l->contor + 1 )
                erase( T->r, pos - T->l->contor - 1 );
            else
            {
                if ( T->l == NIL && T->r == NIL )
                {
                    delete T;
                    T = NIL;
                }
                else
                {
                    if ( T->l->priority > T->r->priority )
                    {
                        rotateRight( T );
                        erase( T->r, pos - T->l->contor - 1 );
                    }
                    else
                    {
                        rotateLeft( T );
                        erase( T->l, pos );
                    }
                }
            }

        if ( T != NIL )
            T->update();
    }

    void split( Node &root, Node &L, Node &R, int pos )
    {
        insert( root, pos, 1, INF );
        L = root->l;
        R = root->r;
        delete root;
        root = NIL;
    }

    void merge( Node &root, Node &L, Node &R )
    {
        root = new _Node( 0, INF, 1, L, R );
        root->update();
        erase( root, root->l->contor + 1 );
    }

    Node root, NIL;
    const static int INF = 1e9;

    void afis(Node T)
    {
        if ( T == NIL ) return;
        afis(T->l);
        cout << T->key << " ";
        afis(T->r);
    }

public:

    Treap()
    {
        srand( time(NULL) );
        NIL = new _Node( -INF, 0, 0, NULL, NULL );
        root = NIL;
    }

    void insert( int pos, int key )
    {
        insert( root, pos, key );
    }

    void erase( int pos )
    {
        erase( root, pos );
    }

    int query( int x, int y )
    {
        int sol = 0;

        Node tmp, T1, T2, T3;

        split( root, T1, T2, y + 1 );
        split( T1, T3, tmp, x );

        sol = tmp->maxim;

        merge( T1, T3, tmp );
        merge( root, T1, T2 );

        return sol;
    }

    void update( int x, int value )
    {
        erase( root, x );
        insert( root, x, value );
    }

    void afis()
    {
        afis(root);
    }
};

int N, M, tip, a, b;

int main()
{
    ifstream in("arbint.in");
    ofstream out("arbint.out");

    in >> N >> M;

    Treap T;

    for ( int i = 1; i <= N; ++i )
    {
        in >> a;
        T.insert( i, a );
    }

    while ( M-- )
    {
        in >> tip >> a >> b;

        if ( tip == 0 )
        {
            out << T.query( a, b ) << "\n";
        }
        else
        {
            T.update( a, b );
        }
    }

    return 0;
}