Cod sursa(job #3365358)

Utilizator prodsevenStefan Albu prodseven Data 20 septembrie 2026 10:00:03
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.37 kb
#include <fstream>
#include <vector>

using namespace std;

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

int n, m;
const int BLOCK_SIZE = 350;

class SqrtDecomp {
    vector<int> v, b;
    int size;
public:
    SqrtDecomp(int size) {
        this->size = size;
        v.assign(size + 2, 0);
        b.assign(BLOCK_SIZE, 0);
    }
    void set(int pos, int val) {
        v[pos] = val;
    }
    void preprocess() {
        for (int i = 0 ; i < n ; ++i) {
            b[i / BLOCK_SIZE] = max(b[i / BLOCK_SIZE], v[i]);
        }
    }
    void update(int pos, int val) {
        int pos_block = pos / BLOCK_SIZE;
        // we're updating the block maximum, so we have to recompute it
        if (b[pos_block] == v[pos] && val < v[pos]) {
            v[pos] = val;
            b[pos_block] = val;
            for (int i = pos_block * BLOCK_SIZE ; i < n && i < (pos_block + 1) * BLOCK_SIZE ; ++i) {
                b[pos_block] = max(b[pos_block], v[i]);
            }
        } else {
            v[pos] = val;
            b[pos_block] = max(b[pos_block], v[pos]);
        }
    }
    int query(int query_left, int query_right) {
        int mx = 0;
        int query_left_block = query_left / BLOCK_SIZE, query_right_block = query_right / BLOCK_SIZE;
        if (query_left_block == query_right_block) {
            for (int i = query_left ; i <= query_right ; ++i) {
                mx = max(mx, v[i]);
            }
        } else {
            // incomplete left part of blocks
            for (int i = query_left ; i <= (query_left_block + 1) * BLOCK_SIZE - 1 ; ++i) {
                mx = max(mx, v[i]);
            }
            // blocks
            for (int i = query_left_block + 1 ; i <= query_right_block - 1 ; ++i) {
                mx = max(mx, b[i]);
            }
            // incomplete right part of blocks
            for (int i = query_right_block * BLOCK_SIZE ; i <= query_right ; ++i) {
                mx = max(mx, v[i]);
            }
        }
        return mx;
    }
};

int main() {
    cin >> n >> m;
    int x;
    SqrtDecomp sd(n);
    for (int i = 0 ; i < n ; ++i) {
        cin >> x;
        sd.set(i, x);
    }
    sd.preprocess();
    while (m--) {
        int cer, a, b; cin >> cer >> a >> b;
        if (cer == 0) {
            a--; b--;
            cout << sd.query(a, b) << "\n";
        }
        if (cer == 1) {
            a--;
            sd.update(a, b);
        }
    }
}