Cod sursa(job #2272241)

Utilizator LucianTLucian Trepteanu LucianT Data 29 octombrie 2018 21:23:36
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.55 kb
#include <fstream>
#include <cmath>
using namespace std;

const int maxN=1e5+2;

int v[maxN];
int n,q,sqroot;
int bucket[maxN];

inline int getBucket(int pos){
    return (pos-1)/sqroot+1;
}

void build(){
    for(int i=1; i<=n; i++)
        if(i%sqroot==1)
            bucket[(i-1)/sqroot+1]=v[i];
        else
            bucket[(i-1)/sqroot+1]=max(v[i],bucket[(i-1)/sqroot+1]);
}

void update(int pos,int val){
    v[pos]=val;
    int where=getBucket(pos);

    bucket[where]=v[(where-1)*sqroot+1];
    for(int i=(where-1)*sqroot+2; i<=where*sqroot; i++)
        bucket[where]=max(bucket[where],v[i]);
}

int bruteQuery(int st,int dr){
    int res=0;
    for(int i=st; i<=dr; i++)
        res=max(res,v[i]);

    return res;
}

int query(int st,int dr){
    int leftBucket=getBucket(st);
    int rightBucket=getBucket(dr);

    if(leftBucket==rightBucket)
        return bruteQuery(st,dr);

    int res=0;
    for(int i=st; i<=leftBucket*sqroot; i++)
        res=max(res,v[i]);

    for(int i=leftBucket+1; i<rightBucket; i++)
        res=max(res,bucket[i]);

    for(int i=(rightBucket-1)*sqroot+1; i<=dr; i++)
        res=max(res,v[i]);

    return res;
}

int main()
{
    ifstream f("arbint.in");
    ofstream g("arbint.out");

    f>>n>>q;
    sqroot=sqrt(n)+1;
    for(int i=1; i<=n; i++)
        f>>v[i];

    build();

    while(q--){
        int op,x,y;
        f>>op>>x>>y;

        if(op==0)
            g<<query(x,y)<<'\n';
        else
            update(x,y);
    }

    return 0;
}