Cod sursa(job #2079771)

Utilizator iordache.bogdanIordache Ioan-Bogdan iordache.bogdan Data 1 decembrie 2017 20:09:25
Problema Arbori de intervale Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 4.04 kb
#include <bits/stdc++.h>
using namespace std;

class sqrt_max_structure {
public:
    sqrt_max_structure(const vector<int>& data) :
            BUCKET_SIZE((int)sqrt(data.size())),
            data_(data),
            max_of_bucket_(data.size() / BUCKET_SIZE + 3) {
        for (size_t step = 0, i = 0; i < data.size(); ++step, i += BUCKET_SIZE) {
            max_of_bucket_[step] = -1;
            for (size_t j = i; j < i + BUCKET_SIZE && j < data_.size(); ++j)
                max_of_bucket_[step] = max(max_of_bucket_[step], data_[j]);
        }
    }

    void update(size_t position, int value) {
        size_t bucket = position / BUCKET_SIZE;
        data_[position] = value;

        max_of_bucket_[bucket] = -1;
        for (size_t i = bucket * BUCKET_SIZE; i < (bucket + 1) * BUCKET_SIZE && i < data_.size(); ++i) {
            max_of_bucket_[bucket] = max(max_of_bucket_[bucket], data_[i]);
        }
    }

    int query(size_t left, size_t right) {
        int solution = -1;
        for (size_t i = left; i < (left / BUCKET_SIZE + 1) * BUCKET_SIZE && i < data_.size(); ++i)
            solution = max(solution, data_[i]);
        for (int i = (int)right; i >= ((int)right / BUCKET_SIZE) * BUCKET_SIZE && i >= 0; --i)
            solution = max(solution, data_[i]);
        for (int i = ((int)left / BUCKET_SIZE + 1) * BUCKET_SIZE; i < (int)data_.size() && i < ((int)right / BUCKET_SIZE - 1) * BUCKET_SIZE; ++i)
            solution = max(solution, max_of_bucket_[i]);

        return solution;
    }

private:
    const int BUCKET_SIZE;
    vector< int > data_, max_of_bucket_;
};

class segment_tree {
public:
    segment_tree(const vector<int>& data) :
            size_(data.size()){
        data_.resize(4 * size_);
        build(1, 0, data.size() - 1, data);
    }

    void update(size_t position, int value) {
        update(1, 0, size_ - 1, position, value);
    }

    int query(size_t left, size_t right) {
        return query(1, 0, size_ - 1, left, right);
    }

private:
    void build(int node, size_t left, size_t right, const vector< int >& data) {
        if (left == right) {
            data_[node] = data[left];
            return;
        }

        size_t middle = (left + right) / 2;
        build(2*node, left, middle, data);
        build(2*node+1, middle+1, right, data);

        data_[node] = max(data_[2*node], data_[2*node+1]);
    }

    void update(int node, size_t left, size_t right, size_t position, int value) {
        if (left == right) {
            data_[node] = value;
            return;
        }

        size_t middle = (left + right) / 2;
        if (position <= middle)
            update(2 * node, left, middle, position, value);
        else
            update(2 * node + 1, middle + 1, right, position, value);

        data_[node] = max(data_[2*node], data_[2*node+1]);
    }

    int query(int node, size_t left, size_t right, size_t query_left, size_t query_right) {
        if (query_left <= left && right <= query_right)
            return data_[node];

        size_t middle = (left + right) / 2;
        int maxim = -1;
        if (query_left <= middle)
            maxim = max(maxim, query(2*node, left, middle, query_left, query_right));
        if (middle < query_right)
            maxim = max(maxim, query(2*node+1, middle+1, right, query_left, query_right));

        return maxim;
    }

    size_t size_;
    vector< int > data_;
};

void solve() {
    size_t size, query_count;
    cin >> size >> query_count;

    vector< int > values(size);
    for (auto& it : values)
        cin >> it;

    //segment_tree value_manager(values);
    sqrt_max_structure value_manager(values);

    while (query_count--) {
        int operation, a, b;
        cin >> operation >> a >> b;

        if (operation == 0)
            cout << value_manager.query((size_t)a - 1, (size_t)b - 1) << '\n';
        else
            value_manager.update((size_t)a - 1, b);
    }
}

int main() {
    assert(freopen("arbint.in", "r", stdin));
    assert(freopen("arbint.out", "w", stdout));
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);

    solve();

    return 0;
}