Cod sursa(job #1518814)

Utilizator xtreme77Patrick Sava xtreme77 Data 6 noiembrie 2015 14:45:17
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.83 kb
/**
 * Code by Patrick Sava
 * "Spiru Haret" National College of Bucharest
 **/

# include "fstream"
# include "cstring"
# include "vector"
# include "queue"
# include "bitset"
# include "algorithm"
# include "map"
# include "set"
# include "unordered_map"
# include "deque"
# include "string"
# include "iomanip"
# include "cmath"
# include "stack"
# include "cassert"

const char IN [ ] =  "arbint.in" ;
const char OUT [ ] = "arbint.out" ;

# define pb push_back
# define mp make_pair
# define FORN( a , b , c ) for ( int a = b ; a <= c ; ++ a )
# define FORNBACK( a , b , c ) for ( int a = b ; a >= c ; -- a )

using namespace std ;

const int MAX = 2e5 + 14 ;

ifstream cin ( IN ) ;
ofstream cout ( OUT ) ;

struct Treap {
    int l , r , sz , maxim , val ;
    int p ;
    Treap ( )
    {
        p = rand ( ) + 1 ;
    }
};

Treap T [ MAX ] ;

int R , noduri ;

void update ( int nod )
{
    if ( nod == 0 ) return ;
    T [ nod ].sz = T [ T [ nod ].l ].sz + T [ T [ nod ].r ].sz + 1 ;
    T [ nod ].maxim = max ( T [ nod ].val , max ( T [ T [ nod ].l ].maxim ,  T [ T [ nod ].r ].maxim ) ) ;
}

int poz ( int nod )
{
    return T [ T [ nod ].l ].sz + 1 ;
}

void split ( int root , int &l , int &r , int pos )
{
    if ( root == 0 ){
        l = r = 0 ;
    }
    else {
        int ch = poz ( root ) ;
        if ( ch >= pos ){
            split ( T [ root ].l , l , T [ root ].l , pos ) ;
            r = root ;
        }
        else {
            split ( T [ root ].r , T [ root ].r , r , pos - ch ) ;
            l = root ;
        }
    }
    update ( root ) ;
}

void join ( int &root , int l , int r )
{
    if ( !l or !r ) root = l + r ;
    else {
        if ( T [ l ].p >= T [ r ].p ){
            join ( T [ l ].r , T [ l ].r , r ) ;
            root = l ;
        }
        else {
            join ( T [ r ].l , l , T [ r ].l ) ;
            root = r ;
        }
    }
    update ( root ) ;
}

void insertt ( int &root , int nod , int pos )
{
    int ch = poz ( root ) ;
    if ( T [ root ].p >= T [ nod ].p )
    {
        if ( ch >= pos )
            insertt ( T [ root ].l , nod , pos ) ;
        else insertt ( T [ root ].r , nod , pos - ch ) ;
    }
    else {
        split ( root , T [ nod ].l , T [ nod ].r , pos ) ;
        root = nod ;
    }
    update ( root ) ;
}

void erasee ( int &root , int pos )
{
    int ch = poz ( root ) ;
    if ( ch == pos )
        join ( root , T [ root ].l , T [ root ].r ) ;
    else if ( ch >= pos )
        erasee ( T [ root ].l , pos ) ;
    else erasee ( T [ root ].r , pos - ch ) ;
    update ( root ) ;
}

int Query ( int root , int st , int dr )
{
    /// intervalul [ 1 , size ]
    int a = 1 ;
    int b = T [ root ].sz ;
    if ( b < st or a > dr ) return 0 ; /// disjuncte
    if ( st <= a and b <= dr )
        return T [ root ].maxim ;
    int r = 0 ;
    int ch = poz ( root ) ;
    r = max ( r , Query ( T [ root ].l , st , dr ) ) ;
    r = max ( r , Query ( T [ root ].r , st - ch , dr - ch ) ) ;
    if ( st <= ch and ch <= dr ) r = max ( r , T [ root ].val ) ;
    return r ;
}


int main ( void )
{
    T [ 0 ].val = T [ 0 ].p = 0 ;

    int n , m ;
    cin >> n >> m ;

    FORN ( i , 1 , n )
    {
        int x ;
        cin >> x ;
        T [ ++ noduri ].val = x ;
        insertt ( R , noduri , i ) ;
    }

    while ( m -- )
    {
        int op ;
        cin >> op ;
        if ( op )
        {
            int a , b ;
            cin >> a >> b ;
            T [ ++ noduri ].val = b ;
            erasee ( R , a ) ;
            insertt ( R , noduri , a ) ;
            //insert
        }
        else {
            int a , b ;
            cin >> a >> b ;
            cout << Query ( R , a , b ) << '\n' ;
            //query
        }
    }

    return 0;
}