Cod sursa(job #1581113)

Utilizator danalex97Dan H Alexandru danalex97 Data 26 ianuarie 2016 16:38:28
Problema Arbori de intervale Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 4.4 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
 
ifstream F("arbint.in");
ofstream G("arbint.out");
 
template <class T>
class SegmentTree {
    private:
        vector<T> hold;
        vector<T> withValue;
        vector<bool> updated;
         
        int S;
        int iBeg;
        int iEnd;
        T value;
         
        T neutral() {
            return T(0);
        }
         
        inline void _update_iBeg(int v) {
            iBeg = v;
        }
         
        inline void _update_iEnd(int v) {
            iEnd = v;
        }
         
        inline void _update_value(int v) {
            value = v;
        }
         
        inline int leftIdx(int node) {
            return node * 2;
        }
        inline int rightIdx(int node) {
            return node * 2 + 1;
        }
        T length(int left,int right) {
            return right - left + 1;
        }
        T app(T a, T b, int left, int right) {
            return a > b ? a : b;
        }
         
        void push(int node, int left, int right) {
            if ( !updated[node] ) 
                return;
            updated[node] = false;
             
            T nodeValue = withValue[node];
            int _leftIdx = leftIdx(node);
            int _rightIdx = rightIdx(node);
                 
            hold[_leftIdx]  = nodeValue;
            hold[_rightIdx] = nodeValue;
                 
            hold[node] = app(nodeValue, nodeValue, left, right);
            withValue[_leftIdx]  = nodeValue;
            withValue[_rightIdx] = nodeValue;
             
            updated[_leftIdx]  = true;
            updated[_rightIdx] = true;
        }
         
        inline bool isOutside(int left, int right) {
            return iBeg > right || iEnd < left;
        }
         
        inline bool isInside(int left, int right) {
            return iBeg <= left && right <= iEnd;
        }
         
        void _update(int node, int left, int right) {
            push(node, left, right);
            if ( isOutside(left, right) ) {
                return;
            }
            if ( isInside(left, right) ) {
                withValue[node] = value;
                updated[node] = true;
                push(node, left, right);
                return;
            }
             
            int middle    = (left + right) / 2;
             
            int _leftIdx = leftIdx(node);
            int _rightIdx = rightIdx(node);
             
            _update(_leftIdx, left, middle);
            _update(_rightIdx, middle+1 ,right);
             
            hold[node] = app(hold[_leftIdx], hold[_rightIdx], left, right);
        }
         
        T _query(int node, int left, int right) {
            push(node, left, right);
            if ( isOutside(left, right) ) {
                return neutral();
            }
            if ( isInside(left, right) ) {
                return hold[node];
            }
            int middle    = (left + right) / 2;
             
            int _leftIdx = leftIdx(node);
            int _rightIdx = rightIdx(node);
             
            T v1 = _query(_leftIdx, left, middle);
            T v2 = _query(_rightIdx, middle+1 ,right);
             
            hold[node] = app(hold[_leftIdx], hold[_rightIdx], left, right);
            return app(v1, v2, left, right); 
        }
    public:
         
         
        SegmentTree(int n) {
			S = n;
			hold = vector<T>(n<<2);
			withValue = vector<T>(n<<2);
			updated = vector<bool>(n<<2);
            value = neutral();
            iBeg = iEnd = 0;
        }
         
        int size() {
            return S;
        }
         
        void update(int iBeg, int iEnd, T value) {
            _update_iBeg(iBeg);
            _update_iEnd(iBeg);
            _update_value(value);
            _update(1, 1, S);
        }
         
        T query(int iBeg, int iEnd) {
            _update_iBeg(iBeg);
            _update_iEnd(iEnd);
            return _query(1, 1, S);
        }
};
 
const int N = 200010;

int n, m;
 
int main() {
    F >> n >> m;
	SegmentTree<int> *seg = new SegmentTree<int>(n);
    for (int i = 1, x; i <= n; ++i) {
        F >> x;
        seg -> update(i, i, x);
    }
    for (int i = 1, t, x, y; i <= m; ++i) {
        F >> t >> x >> y;
        if ( t == 1 ) {
            seg -> update(x, x, y);
        } else {
            int ans = seg -> query(x, y);
            G << ans << '\n';
        }
    }
}