Cod sursa(job #2492594)

Utilizator davidegoldDavide Gold davidegold Data 14 noiembrie 2019 23:21:17
Problema Arbori indexati binar Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.98 kb
#include <fstream>
#include <vector>


using namespace std;

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

const int MAXN = 1e5;


/* Given an array A with n elements and 2 type of online operations:
 * 1. 0 a b - compute the maximum in the range A[a..b]
 * 2. 1 a b - change the value of element on position a to be b
 * Return the result for the forst type of operation
 */

template <class T>
class SegmentTree {
    typedef T (*functionType) (T, T);

    public:
        SegmentTree(vector<T> &a, functionType _f):
        f (_f), num_elem (a.size()), st(4*num_elem+1){
            build_segment_tree(1, 0, num_elem-1, a);
        }

        void update_element(int pos, T value){
            update(1, 0, num_elem-1, pos, value);
        }

        T query_segment(int x, int y) {
            query(1, 0, num_elem-1, x, y);
            return ans;
        }



    private:
        functionType f;
        vector<T> st;
        int num_elem;
        T ans;

        void build_segment_tree(int node, int left, int right, vector<T> &a){
            if (left == right) {
                st[node] = a[left];
                return;
            }

            int mid = (right+left) >> 1;
            int left_son = node << 1;
            int right_son = left_son+1;

            build_segment_tree(left_son, left, mid, a);
            build_segment_tree(right_son, mid+1, right, a);
            st[node] = f(st[left_son], st[right_son]);

        }

        void update(int node, int left, int right, int pos, T value){
            if (left == right){
                st[node] = value;
                return;
            }

            int mid = (right+left) >> 1;
            int left_son = node << 1;
            int right_son = left_son+1;

            if (pos <= mid)
                update(left_son, left, mid, pos, value);
            else update(right_son, mid+1, right, pos, value);

            st[node] = f(st[left_son], st[right_son]);

        }

        void query(int node, int left, int right, int x, int y){
            if (x <= left && right <= y){
                // the first range to be taken into
                // consideration when computing the result
                if (left == x) ans = st[node];
                else ans = f(ans, st[node]);
                return;
            }

            int mid = (right+left) >> 1;
            int left_son = node << 1;
            int right_son = left_son + 1;

            if (x <= mid) query(left_son, left, mid, x, y);
            if (mid < y) query(right_son, mid+1, right, x, y);

        }
};


int my_max(int a, int b){
    if (a > b)
        return a;
    return b;
}

int main() {
    int n, m;
    cin >> n >> m;

    vector<int> a(n, 0);
    for (int i = 0; i < n; ++ i){
        cin >> a[i];
    }

    SegmentTree <int> ds(a, my_max);

    while(m--){
        int type, x, y;
        cin >> type >> x >> y;
        x--;
        if (type == 0)
            cout << ds.query_segment(x, --y) << "\n";
        else ds.update_element(x, y);
    }

    return 0;
}