Cod sursa(job #1646183)

Utilizator BrandonChris Luntraru Brandon Data 10 martie 2016 15:21:01
Problema Arbori de intervale Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.07 kb
#include <fstream>
#include <cmath>

#define NMAX 100005
#define SQROOTMAX 320
using namespace std;

ifstream cin("arbint.in");
ofstream cout("arbint.out");

int n, q, sqroot, v[NMAX], segm[SQROOTMAX];

inline void update(int pos, int val) {
    int pos_l, pos_r, curr_intv;

    if(pos % sqroot != 0) {
        pos_l = pos / sqroot * sqroot + 1;
        pos_r = pos_l + sqroot - 1;
        curr_intv = pos / sqroot + 1;
    }
    else {
        pos_l = (pos / sqroot - 1) * sqroot + 1;
        pos_r = pos_l + sqroot - 1;
        curr_intv = pos / sqroot;
    }

    v[pos] = val;
    segm[curr_intv] = 0;

    for(int i = pos_l; i <= pos_r; ++i) {
        segm[curr_intv] = max(segm[curr_intv], v[i]);
    }
}

inline int query(int l, int r) {
    int intv_l, pre_intv, intv_r, post_intv, ans = 0;

    if(l % sqroot != 0) {
        intv_l = l / sqroot + 2;
        pre_intv = (intv_l - 1) * sqroot;
    }
    else {
        intv_l = l / sqroot + 1;
        pre_intv = l;
    }

    if(r % sqroot != 0) {
        intv_r = r / sqroot;
        post_intv = intv_r * sqroot + 1;
    }
    else {
        intv_r = r / sqroot;
        post_intv = r + 1;
    }

    if(pre_intv > post_intv) {
        return v[l];
    }

    for(int i = l; i <= pre_intv; ++i) {
        ans = max(ans, v[i]);
    }

    for(int i = post_intv; i <= r; ++i) {
        ans = max(ans, v[i]);
    }

    for(int i = intv_l; i <= intv_r; ++i) {
        ans = max(ans, segm[i]);
    }

    return ans;
}

int main() {
    cin >> n >> q;

    for(int i = 1; i <= n; ++i) {
        cin >> v[i];
    }

    sqroot = sqrt(n);

    for(int i = 1; i <= sqroot + 1; ++i) {
        for(int j = (i - 1) * sqroot + 1; j <= i * sqroot; ++j) {
            segm[i] = max(segm[i], v[j]);
        }
    }

    for(int i = 1; i <= q; ++i) {
        int a, b;
        bool type;
        cin >> type >> a >> b;

        if(type == 1) {
            update(a, b);
        }
        else {
            cout << query(a, b) << '\n';
        }
    }
    return 0;
}