Cod sursa(job #1587986)

Utilizator sebii_cSebastian Claici sebii_c Data 2 februarie 2016 18:25:23
Problema Arbori de intervale Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.24 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <memory>
#include <limits>

using namespace std;

class interval_tree {
    struct Node {
	int val;
	int left_edge, right_edge;
	
	shared_ptr<Node> left_node;
	shared_ptr<Node> right_node;

	Node(const vector<int>& values, int l, int r) {
	    if (l == r) {
		val = values[l];
	    } else {
		int m = l + (r - l) / 2;
		left_node = make_shared<Node>(Node(values, l, m));
		right_node = make_shared<Node>(Node(values, m + 1, r));
		val = max(left_node->val, right_node->val);
	    }
	    left_edge = l, right_edge = r;
	}
	
	/**@brief Update interval [l, r] with new value
	 */
	void update(int l, int r, int new_value) {
	    if (l <= left_edge && right_edge <= r) {
		val = new_value;
	    } else {
		int mid = left_edge + (right_edge - left_edge) / 2;
		if (l <= mid) 
		    left_node->update(l, mid, new_value);
		if (r > mid)
		    right_node->update(mid + 1, r, new_value);
		
		val = max(left_node->val, right_node->val);
	    }
	}

	/**@brief Query interval [l, r] for maximum value
	 */
	int query(int l, int r) {
	    if (l <= left_edge && right_edge <= r) {
		return val;
	    } else {
		int mid = left_edge + (right_edge - left_edge) / 2;
		int left_val = numeric_limits<int>::min();
		int right_val = numeric_limits<int>::min();
		
		if (l <= mid)
		    left_val = left_node->query(l, mid);
		if (r > mid)
		    right_val = right_node->query(mid + 1, r);

		return max(left_val, right_val);
	    }
	}
    };
    
    Node root;

public:
    interval_tree(const vector<int>& values):
	root(Node(values, 0, values.size() - 1)) {}

    void update(int l, int r, int new_value) {
	root.update(l, r, new_value);
    }

    int query(int l, int r) {
	return root.query(l, r);
    }
};

int main() {
    int n, m;
    ifstream fin("arbint.in");
    ofstream fout("arbint.out");

    fin >> n >> m;
    vector<int> v(n);
    for (int i = 0; i < n; ++i) {
	fin >> v[i];
    }
    interval_tree tree(v);
    
    for (int i = 0; i < m; ++i) {
	int l, r, type;
	fin >> type >> l >> r;
	if (type == 0) {
	    fout << tree.query(l - 1, r - 1) << endl;
	} else {
	    tree.update(l - 1, l - 1, r);
	}
    }
    
    return 0;
}