Cod sursa(job #1648580)

Utilizator BrandonChris Luntraru Brandon Data 11 martie 2016 10:51:54
Problema Arbori de intervale Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.15 kb
#include <fstream>
#include <cmath>

#define NMAX 100005
#define SQROOTMAX 320
#define INF 0x3f3f3f3f
using namespace std;

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

class SegmentPosition {
public:
    int left, right;
};

SegmentPosition segm_pos[SQROOTMAX];
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_qr, int r_qr) {
    /*int intv_l, pre_intv, intv_r, post_intv, ans = 0;

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

    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) {
        post_intv = r + 1;
        --pre_intv;
    }

    if(intv_l > intv_r) {
        for(int i = l; i <= r; ++i) {
            ans = max(ans, v[i]);
        }
    }

    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]);
    }*/

    int ans = 0, l = INF, r = -1;

    for(int i = 1; i <= sqroot + (n % sqroot != 0); ++i) {
        if(l_qr <= segm_pos[i].left and r_qr >= segm_pos[i].right) {
            if(l > segm_pos[i].left) {
                l = segm_pos[i].left;
            }
            if(r < segm_pos[i].right) {
                r = segm_pos[i].right;
            }
            ans = max(ans, segm[i]);
        }
    }

    if(l == INF and r == -1) {
        l = r_qr;
        r = r_qr + 1;
    }

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

    for(int i = r; i <= r_qr; ++i) {
        ans = max(ans, v[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) {
        segm_pos[i].left = (i - 1) * sqroot + 1;
        segm_pos[i].right = i * sqroot;

        for(int j = segm_pos[i].left; j <= segm_pos[i].right; ++j) {
            segm[i] = max(segm[i], v[j]);
        }
    }

    if(n % sqroot == 0) {
        segm[sqroot + 1] = -1;
    }

    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;
}