Cod sursa(job #2446920)

Utilizator ZanoxNonea Victor Zanox Data 11 august 2019 11:54:42
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.2 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <assert.h>


using namespace std;

//conventie: indexare de la 0 la n-1
//arb[i][j] maximul in intervalul [2^i * j, 2^i * (j + 1)]
//cand intervalul iese din domeniul vectorului original, restul de elemente sunt considerate 0

ifstream fin("arbint.in");
ofstream fout("arbint.out");

int n, nPadded, noOp, maxPow;
vector<vector<int>> arb;

void update(int i, int val);
int query(int i, int j);

int main() {
    fin>>n>>noOp;

    nPadded = 1;
    maxPow = 0;

    while (nPadded < n) {
        nPadded *= 2; //overflow?
        maxPow++;
    }

    arb.resize(maxPow + 1);
    for (int i = 0; i <= maxPow; i++)
        arb[i].resize(nPadded / (1<<i), 0); //value second arg?

    for (int i = 0; i < n; i++) {
        fin>>arb[0][i];
    }

    for (int i = 1; i <= maxPow; i++)
        for (int j = 0; j < arb[i].size(); j++)
        arb[i][j] = max(arb[i-1][2 * j], arb[i-1][2 * j + 1]);

    for (int i = 0; i < noOp; i++) {
        int q;
        fin>>q;

        int a, b;
        fin>>a>>b;

        if (q == 0) {
            fout<<query(a - 1, b - 1)<<'\n';
        } else {
            assert(q == 1);
            update(a - 1, b);
        }
    }
}

void update(int i, int val) {
    arb[0][i] = val;
    i /= 2;

    for (int j = 1; j <= maxPow; j++, i/=2)
        arb[j][i] = max(arb[j-1][2 * i], arb[j-1][2 * i + 1]);
}


int query(int i, int j) {

    if (i > j) return 0;

    if (i == j) return arb[0][i];

    int length = 1;
    int pow = 0;


    while (2 * length <= (j - i + 1) / 2) {
        length *= 2;
        pow ++;
    }

    {
        int length2 = length * 2;
        int offset = i / length2 * length2;
        if (offset < i) offset += length2;

        if (offset + length2 - 1 <= j) {
            length *= 2;
            pow++;
        }
    }

    assert (pow <= maxPow);

    int offset = i / length * length;
    if (offset < i) offset += length;

    assert (offset >= i);

    assert (offset/length < arb[pow].size());
    int rez = arb[pow][offset / length];

    return max(query(i, offset - 1), max(rez, query(offset + length, j)));
}