Cod sursa(job #2575228)

Utilizator rd211Dinucu David rd211 Data 6 martie 2020 12:17:41
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda imded Marime 1.59 kb
#include <bits/stdc++.h>

using namespace std;
const int NMAX = 4*100005;
ifstream fin("arbint.in");
ofstream fout("arbint.out");

int delta[NMAX];
int maxim[NMAX];
int lo[NMAX];
int hi[NMAX];
int saved[NMAX];
int n, m;
void init(int i, int a, int b)
{
    int mediu = (a+b)/2;
    lo[i]=a;
    hi[i]=b;
    if(a==b)return;
    init(2*i, a,mediu);
    init(2*i+1, mediu+1,b);
}
void probagate(int i)
{
    delta[2*i]+=delta[i];
    delta[2*i+1]+=delta[i];
    delta[i] = 0;
}
void update(int i)
{
    maxim[i] = max(maxim[2*i]+delta[2*i],
                   maxim[2*i+1]+delta[2*i+1]);
}
void increment(int i, int a, int b, int val)
{
    if(lo[i]>b || hi[i]<a) return;

    if(lo[i]>=a && hi[i]<=b) {delta[i]+=val;return;}
    probagate(i);
    increment(2*i,a,b,val);
    increment(2*i+1,a,b,val);
    update(i);

}
int query(int i, int a, int b)
{
    if(lo[i]>b || hi[i]<a) return -1;

    if(lo[i]>=a && hi[i]<=b) {return maxim[i]+delta[i];}
    probagate(i);
    int leftv = query(2*i,a,b);
    int rightv = query(2*i+1,a,b);
    update(i);
    return max(leftv,rightv);
}

int main()
{
    fin>>n>>m;
    init(1,0,n-1);
    for(int i = 0;i<n;i++)
    {
        int a;
        fin>>a;
        increment(1,i,i,a);
        saved[i]=a;
    }
    while(m--)
    {
        int c, a, b;
        fin>>c>>a>>b;
        if(c==1)
        {
            a--;
            increment(1,a,a,b-saved[a]);
            saved[a]=b;
        }
        else
        {
            a--,b--;
            fout<<query(1,a,b)<<'\n';
        }
    }
    return 0;
}