Cod sursa(job #2198025)

Utilizator ajeccAjechiloae Eugen ajecc Data 23 aprilie 2018 13:26:00
Problema Arbori de intervale Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 8.04 kb
#include <bits/stdc++.h>
#define for0(i, n) for(int i = 0; i < n; i++)
#define for1(i, n) for(int i = 1; i <= n; i++)
#define pb push_back
#define mp make_pair
#define all(v) v.begin(), v.end()
#define V vector<int>
#define VP vector<pair<int, int> >
#define FASTIO ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
using namespace std;
#ifdef _WIN32
#include <windows.h>
#define print(x) PRINT(x, #x)
template<typename T> inline const void PRINT(T VARIABLE, string NAME)
{
#ifndef ONLINE_JUDGE /// ONLINE_JUDGE IS DEFINED ON CODEFORCES
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hConsole, 10);
    cerr << NAME << " = " << VARIABLE;
    SetConsoleTextAttribute(hConsole, 7);
    cerr << '\n';
#endif
}
#else
#define print(x) 0
#endif
typedef long long ll;
typedef unsigned long long ull;
const ll INFLL = 2 * (ll)1e18 + 100;
const int INFINT = 2 * (int)1e9 + 100;
const double PI = atan(1) * 4;
const double EPS = 1e-12;
const int SEED = 1e3 + 7;

const int MOD = 1e9 + 7; /// careful here (7 or 9, 66.. etc)
const int NMAX = 1e5 + 5;

template <typename T>
class SEGMENT_TREE
{
private:

    int tree_size;

    bool seg_tree_is_constructed, base_function_is_set, neutral_element_is_set;
    T *seg_tree;
    function<T(T, T)> base_function;

    bool debug()
    {
        bool ret = 0;
        if(!seg_tree_is_constructed)
            cerr << "CONSTRUCT SEGMENT TREE\n";

        if(!base_function_is_set)
            cerr << "SET BASE FUNCTION\n";

        if(!neutral_element_is_set)
            cerr << "SET NEUTRAL ELEMENT\n";

        ret = (!base_function_is_set) | (!seg_tree_is_constructed) | (!neutral_element_is_set);
        return ret;
    }
    void construct_seg_tree(int _tree_size)
    {
        if(seg_tree_is_constructed) return;
        seg_tree = new T[4 * _tree_size];
        tree_size = 4 * _tree_size;
        seg_tree_is_constructed = true;
    }


    bool lazy_is_constructed, lazy_function_is_set, lazy_propagation_function_is_set;
    T *lazy;
    T neutral_element;
    function<T(T, T)> lazy_propagation_function;
    function<T(T, T, T)> lazy_function;

    bool debug_lazy()
    {
        bool ret = 0;
        ret |= debug();

        if(!lazy_is_constructed)
            cerr << "TO USE RANGE_UPDATE YOU NEED LAZY PROPAGATION\n";

        if(!lazy_function_is_set)
            cerr << "TO USE LAZY PROPAGATION YOU NEED A LAZY FUNCTION\n";

        if(!lazy_propagation_function_is_set)
            cerr << "SET LAZY -> PROPAGATION <- FUNCTION \n";

        ret |= (!lazy_is_constructed) | (!lazy_function_is_set) | (!lazy_propagation_function_is_set);
        return ret;
    }
    void construct_lazy(int _tree_size)
    {
        if(lazy_is_constructed) return;
        lazy = new T[4 * _tree_size];
        lazy_is_constructed = true;
    }

    void process_lazy(int nod, int len)
    {
        if(debug_lazy()) return;
        if(lazy[nod] != neutral_element)
        {
            seg_tree[nod] = lazy_function(lazy[nod], seg_tree[nod], len);
            if(2 * nod < tree_size)
                lazy[2 * nod] = lazy_propagation_function(lazy[2 * nod], lazy[nod]);
            if(2 * nod + 1 < tree_size)
                lazy[2 * nod + 1] = lazy_propagation_function(lazy[2 * nod + 1], lazy[nod]);
            lazy[nod] = neutral_element;
        }
    }

    void initialize()
    {
        tree_size = 0;
        seg_tree_is_constructed = base_function_is_set = neutral_element_is_set = false;
        lazy_is_constructed = lazy_function_is_set = lazy_propagation_function_is_set = false;
    }

public:

    SEGMENT_TREE()
    {
        tree_size = 0;
        seg_tree_is_constructed = base_function_is_set = false;
        lazy_is_constructed = neutral_element_is_set = lazy_function_is_set = lazy_propagation_function_is_set = false;
        cerr << "CONSTRUCT THE SEGMENT TREE FIRST\n";
    }

    SEGMENT_TREE(int _tree_size, function<T(T, T)> _base_function, T _neutral_element)
    {
        initialize();
        lazy_is_constructed = lazy_function_is_set = lazy_propagation_function_is_set = false;
        construct_seg_tree(_tree_size);
        set_base_function(_base_function);
        set_neutral_element(_neutral_element);
        memset(seg_tree, sizeof(seg_tree), 0);
    }
    SEGMENT_TREE(int _tree_size, function<T(T, T)> _base_function, T _neutral_element, function<T(T, T, T)> _lazy_function, function<T(T, T)> _lazy_propagation_function)
    {
        initialize();
        construct_seg_tree(_tree_size);
        set_base_function(_base_function);
        construct_lazy(_tree_size);
        set_neutral_element(_neutral_element);
        set_lazy_function(_lazy_function);
        set_lazy_propagation_function(_lazy_propagation_function);
        memset(seg_tree, sizeof(seg_tree), _neutral_element);
        memset(lazy, sizeof(lazy), _neutral_element);
    }

    void set_base_function(function<T(T, T)> _base_function)
    {
        base_function = _base_function;
        base_function_is_set = true;
    }
    void set_neutral_element(T _neutral_element)
    {
        neutral_element = _neutral_element;
        neutral_element_is_set = true;
    }
    void set_lazy_function(function<T(T, T, T)> _lazy_function)
    {
        lazy_function = _lazy_function;
        lazy_function_is_set = true;
    }
    void set_lazy_propagation_function(function<T(T, T)> _lazy_propagation_function)
    {
        lazy_propagation_function = _lazy_propagation_function;
        lazy_propagation_function_is_set = true;
    }

    void update(int nod, int l, int r, int pos, T val)
    {
        if(debug()) return;

        if(lazy_is_constructed)
            process_lazy(nod);

        if(l == r)
        {
            seg_tree[nod] = val;
            return;
        }
        int m = (l + r) / 2;
        if(pos <= m) update(2 * nod, l, m, pos, val);
        else update(2 * nod + 1, m + 1, r, pos, val);

        seg_tree[nod] = base_function(seg_tree[2 * nod], seg_tree[2 * nod + 1]);
    }

    void range_update(int nod, int l, int r, int start, int finish, T val)
    {
        if(debug_lazy()) return;

        if(l >= start && r <= finish) lazy[nod] = lazy_propagation_function(lazy[nod], val);
        process_lazy(nod, r - l + 1);

        if(l > finish || r < start) return;
        if(l >= start && r <= finish) return;

        int m = (l + r) / 2;
        range_update(2 * nod, l, m, start, finish, val);
        range_update(2 * nod + 1, m + 1, r, start, finish, val);

        seg_tree[nod] = base_function(seg_tree[2 * nod], seg_tree[2 * nod + 1]);
    }

    T query(int nod, int l, int r, int start, int finish)
    {
        if(debug()) return neutral_element;
        if(lazy_is_constructed && debug_lazy()) return  neutral_element;

        if(lazy_is_constructed)
            process_lazy(nod, r - l + 1);

        if(l >= start && r <= finish) return seg_tree[nod];
        if(l > finish || r < start) return neutral_element;

        int m = (l + r) / 2;
        T L = query(2 * nod, l, m, start, finish);
        T R = query(2 * nod + 1, m + 1, r, start, finish);

        return base_function(L, R);
    }

}; /// lazy_function needs the parameters (lazy, seg_tree[nod], len) in this order



ll cmp(ll a, ll b)
{
    return a + b;
}

ll fct(ll a, ll b, ll len)
{
    return b + len * a;
}

int main()
{
    ifstream cin("arbint.in");
    ofstream cout("arbint.out");
    int n, q;
    SEGMENT_TREE<int> seg_tree(NMAX, cmp, 0);

    cin >> n >> q;
    for1(i, n)
    {
        int a;
        cin >> a;
        seg_tree.update(1, 1, n, i, a);
    }

    while(q--)
    {
        int t;
        cin >> t;
        if(t == 1)
        {
            int pos, val;
            cin >> pos >> val;
            seg_tree.update(1, 1, n, pos, val);
        }
        else
        {
            int l, r;
            cin >> l >> r;
            cout << seg_tree.query(1, 1, n, l, r) << '\n';
        }

    }

    return 0;
}