Cod sursa(job #2750263)

Utilizator smoc_georgemarianSmoc George-Marian smoc_georgemarian Data 10 mai 2021 14:10:57
Problema Arbori de intervale Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.79 kb
#include <iostream>
#include <fstream>
#include <vector>
#define int long long int
#define double long double
#define cin fin
#define cout fout
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
template <class T>
class arbint
{  
    vector<T> lazy;
    vector<T> tree;
    const int NMAX;
     T getmax( const T& val1, const T& val2)
    {
        if( val1>val2)
           return val1;
        return val2;
    }
public:
   
    arbint(int value): NMAX(4*value+9)
    {
        lazy.reserve(NMAX);
        tree.reserve(NMAX);
    }
    void updateRangeUtil(int si, int ss, int se, int us,
                         int ue, const T& diff)
    {
        if (lazy[si] != 0)
        {
            tree[si] += (se - ss + 1) * lazy[si];
            if (ss != se)
            {
                lazy[si * 2 + 1] += lazy[si];
                lazy[si * 2 + 2] += lazy[si];
            }
            lazy[si] = 0;
        }

        if (ss > se || ss > ue || se < us)
            return;
        if (ss >= us && se <= ue)
        {
            tree[si] += (se - ss + 1) * diff;
            if (ss != se)
            {
                lazy[si * 2 + 1] += diff;
                lazy[si * 2 + 2] += diff;
            }
            return;
        }

        int mid = (ss + se) / 2;
        updateRangeUtil(si * 2 + 1, ss, mid, us, ue, diff);
        updateRangeUtil(si * 2 + 2, mid + 1, se, us, ue, diff);
        tree[si] = getmax(tree[si * 2 + 1] , tree[si * 2 + 2]);
    }
    void updateRange(int n, int us, int ue, const T& diff)
    {
        updateRangeUtil(0, 0, n - 1, us, ue, diff);
    }
    T getMaxUtil(int ss, int se, int qs, int qe, int si)
    {
        if (lazy[si] != 0)
        {
            tree[si] += (se - ss + 1) * lazy[si];
            if (ss != se)
            {
                lazy[si * 2 + 1] += lazy[si];
                lazy[si * 2 + 2] += lazy[si];
            }

            lazy[si] = 0;
        }

        if (ss > se || ss > qe || se < qs)
            return 0;

        if (ss >= qs && se <= qe)
            return tree[si];

        int mid = (ss + se) / 2;
        return getmax( getMaxUtil(ss, mid, qs, qe, 2 * si + 1) ,
               getMaxUtil(mid + 1, se, qs, qe, 2 * si + 2) );
    }
    T getMax(int n, int qs, int qe)
    {
        if (qs < 0 || qe > n - 1 || qs > qe)
        {
            printf("Invalid Input");
            return -1;
        }

        return getMaxUtil(0, n - 1, qs, qe, 0);
    }
    void constructSTUtil(const vector<T>& arr, int ss, int se, int si)
    {
        if (ss > se)
            return;
        if (ss == se)
        {
            tree[si] = arr[ss];
            return;
        }

        int mid = (ss + se) / 2;
        constructSTUtil(arr, ss, mid, si * 2 + 1);
        constructSTUtil(arr, mid + 1, se, si * 2 + 2);

        tree[si] = getmax( tree[si * 2 + 1] , tree[si * 2 + 2]);
    }

    void constructST(const vector<T>& arr, int n)
    {
        constructSTUtil(arr, 0, n - 1, 0);
    }
    /*usage
    vector<int>sol;
    sol.push_back(0);
    sol.push_back(numere);
    
    arbint<int>a(sol.size());
    a.constructST(sol,sol.size());
    a.getMax(sol.size(),st,dr);
    a.updateRange(sol.size(),st,dr, add);
    
    */
};
int32_t main()
{
    int n,m,i;
    vector<int> sol;
    sol.push_back(0);
    cin>>n>>m;
    
    for(i=1;i<=n;i++)
       {
           int x;
           cin>>x;
           sol.push_back(x);
       }
    arbint<int> a(sol.size());
    a.constructST(sol,sol.size());
    for(i=1;i<=m;i++)
        {
            int c,x,y;
            cin>>c>>x>>y;
            if(c==0)
               cout<<a.getMax(sol.size(),x,y)<<'\n';
               else
               {
                   int value= a.getMax(sol.size(),x,x);
                   int cat= y-value;
                   a.updateRange(sol.size(),x,x,cat);
               }
        }
    return 0;
}