Cod sursa(job #2815619)

Utilizator Victor2006Nicola Victor-Teodor Victor2006 Data 9 decembrie 2021 22:14:28
Problema Arbori de intervale Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.06 kb
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <queue>
#define QUERY 0
#define UPDATE 1
#define INF 1000000000
#define N 100000
#define SQN 512
const int BSIZE = (N - 1) / SQN + 1;

using std::max;
using std::priority_queue;

int v[N];
int batog[BSIZE];
priority_queue <int> heap[BSIZE];
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] );
        heap[i / SQN].push( v[i] );
    }
}

void update( int poz, int val ) {
    int bucket = getBucket( poz );
    if ( heap[bucket].top() == v[poz] )
        heap[bucket].pop();
    v[poz] = val;
    heap[bucket].push( val );
    batog[bucket] = heap[bucket].top();
}

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 += SQN )
        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 );
    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;
}