Cod sursa(job #2815028)

Utilizator Victor2006Nicola Victor-Teodor Victor2006 Data 8 decembrie 2021 23:42:04
Problema Arbori de intervale Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.03 kb
#include <stdio.h>
#include <math.h>
#include <algorithm>
#define QUERY 0
#define UPDATE 1
#define INF 1000000000

using std::max;

int SQN;
int BSIZE;

int* v;
int* batog;
int n;

inline int getBucket( int poz ) { return poz / SQN; }
inline int firstPosBucket( int bucket ) { return bucket * SQN; }
inline int lastPosBucket( int bucket ) { return firstPosBucket( bucket ) + SQN - 1; }

void build() {
    for ( int i = 0; i < BSIZE; i ++ )
        batog[i] = 0;
    for ( int i = 0; i < n; i ++ )
        batog[i / SQN] = max( batog[i / SQN], v[i] );
}

void update( int poz, int val ) {
    int st, dr, bucket = getBucket( poz );
    st = firstPosBucket( bucket );
    dr = lastPosBucket( bucket );
    batog[bucket] = 0;
    v[poz] = val;
    for ( int i = st; i <= dr; i ++ )
        batog[bucket] = max( batog[bucket], v[i] );
}

int query( int st, int dr ) {
    int ans = -INF, lb, rb;

    lb = lastPosBucket( getBucket( st ) );
    rb = firstPosBucket( getBucket( dr ) );

    if ( lb > rb ) { // nu am niciun bucket in interval
        while ( st <= dr )
            ans = max( ans, v[st ++] );
        return ans;
    }

    while ( st <= lb )
        ans = max( ans, v[st ++] );
    for ( ; st < rb; st ++ )
        ans = max( ans, batog[getBucket( st )] );
    while ( st <= dr )
        ans = max( ans, v[st ++] );
    return ans;
}

int main() {
    FILE *fin, *fout;
    int q, pb, a, b;

    fin = fopen( "arbint.in", "r" );
    fout = fopen( "arbint.out", "w" );
    fscanf( fin, "%d%d", &n, &q );

    SQN = sqrt( n );
    BSIZE = (n - 1) / SQN + 1;
    v = new int[n];
    batog = new int[BSIZE];

    for ( int i = 0; i < n; i ++ )
        fscanf( fin, "%d", &v[i] );
    build();
    for ( int i = 0; i < q; i ++ ) {
        fscanf( fin, "%d%d%d", &pb, &a, &b );
        if ( pb == QUERY )
            fprintf( fout, "%d\n", query( a - 1, b - 1 ) );
        else if ( pb == UPDATE )
            update( a - 1, b );
    }
    fclose( fin );
    fclose( fout );
    return 0;
}