Cod sursa(job #2049397)

Utilizator BogdanisarBurcea Bogdan Madalin Bogdanisar Data 27 octombrie 2017 09:35:41
Problema Arbori de intervale Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.29 kb
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <algorithm>
#include <queue>
#include <unordered_map>

using namespace std;
ifstream in("arbint.in");
ofstream out("arbint.out");

#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
const int NMax = 1e5 + 5;
const ll inf = 1e18 + 5;

// rezolvare cu smenul lui Batog;

int N,M,root;
int v[NMax],batog[NMax];
// root - o aproximare a sqrt(N);
// v[i] - vectorul din input pe care se fac modificari;
// batog[i] - maximul de pe intervalul [(i-1)*root+1,i*root];

void update(int,int);
// update(int i,int val) - schimba v[i] in val,
// dar modifica si informatiile asociate acestuia din vectorul batog;
int query(int,int);
// query(a,b) - returneaza maximul din intervalul [a,b];

int main() {
    in>>N>>M;

    for (root=1;root*root <= N;++root) ;
    --root;

    for (int i=1;i <= N;++i) {
        in>>v[i];

        // initializare a vectorului batog;
        // idx - reprezinta numarul de ordine a bucatelei de sqrt(N) in care se afla elementul cu pozitia i;
        int idx = (i-1)/root + 1;
        batog[idx] = max(batog[idx],v[i]);
    }

    while (M--) {
        int tip,x,y;
        in>>tip>>x>>y;

        if (tip == 1) {
            update(x,y);
        }
        else {
            out<<query(x,y)<<'\n';
        }
    }

    in.close();out.close();
    return 0;
}

void update(int i,int val) {
    int idx = (i-1)/root + 1,
        st = (idx-1)*root + 1,
        dr = idx*root;

    batog[idx] = 0;
    v[i] = val;
    for (int j=st;j <= dr;++j) {

        batog[idx] = max(batog[idx],v[j]);
    }
}

int query(int a,int b) {
    int mx = 0;

    // se parcurg elementele de la stanga bucatelelor de sqrt(N) cuprinse in intregime;
    int j = a;
    while ((j-1) % root != 0 && j <= b) {
        mx = max(mx,v[j]);
        ++j;
    }

    // se parcurg bucatile de sqrt(N) cuprinse in intregime;
    while (j+root-1 <= b) {
        int idx = (j-1)/root + 1;
        mx = max(mx,batog[idx]);

        j += root;
    }

    // se parcurg elementele de la dreapta bucatelelor de sqrt(N) cuprinse in intregime;
    while (j <= b) {
        mx = max(mx,v[j]);
        ++j;
    }

    return mx;
}