Cod sursa(job #2867256)

Utilizator the_horoHorodniceanu Andrei the_horo Data 10 martie 2022 11:42:15
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.83 kb
#include <array>
#include <cstdint>
#include <fstream>
#include <vector>


using u32 = uint32_t;

constexpr size_t MAX_NODES = 100000;

std::array<u32, MAX_NODES * 4> arbint;
std::array<u32, MAX_NODES> ogValues;

size_t LEFT (size_t node) { return node * 2 + 1; }
size_t RIGHT (size_t node) { return node * 2 + 2; }
size_t MIJ (size_t lhs, size_t rhs) { return lhs + (rhs - lhs) / 2; }


void build (size_t node, size_t intLeft, size_t intRight) {
    if (intLeft == intRight - 1) {
        arbint[node] = ogValues[intLeft];
        return;
    }

    const size_t mij = MIJ(intLeft, intRight);

    build(LEFT(node), intLeft, mij);
    build(RIGHT(node), mij, intRight);

    arbint[node] = std::max(arbint[LEFT(node)], arbint[RIGHT(node)]);
}


void update (size_t index, u32 value, size_t node, size_t intLeft, size_t intRight) {
    if (intRight - 1 == intLeft && intLeft == index) {
        arbint[node] = value;
        return;
    }

    const size_t mij = MIJ(intLeft, intRight);

    if (index < mij)
        update(index, value, LEFT(node), intLeft, mij);
    else
        update(index, value, RIGHT(node), mij, intRight);

    arbint[node] = std::max(arbint[LEFT(node)], arbint[RIGHT(node)]);
}

u32 query (size_t left, size_t right, size_t node, size_t intLeft, size_t intRight) {
    if (left <= intLeft && intRight <= right)
        return arbint[node];

    if (left >= intRight || right <= intLeft)
        return 0;

    const size_t mij = MIJ(intLeft, intRight);

    u32 max = 0;

    if (left < mij)
        max = std::max(max, query(left, right, LEFT(node), intLeft, mij));
    if (mij < right)
        max = std::max(max, query(left, right, RIGHT(node), mij, intRight));

    return max;
}

void debugArbint (size_t node, size_t intLeft, size_t intRight) {
    if (intLeft >= intRight)
        return;

    std::fprintf(stderr, "For [%zu, %zu) I have associated maximum: %u\n", intLeft, intRight, arbint[node]);

    if (intLeft != intRight - 1) {
        const size_t mij = MIJ(intLeft, intRight);
        debugArbint(LEFT(node), intLeft, mij);
        debugArbint(RIGHT(node), mij, intRight);
    }
}


int main () {
    std::ifstream in("arbint.in");
    std::ofstream out("arbint.out");

    size_t numberCount, queryCount;
    in >> numberCount >> queryCount;

    for (size_t i = 0; i != numberCount; ++ i)
        in >> ogValues[i];

    build(0, 0, numberCount);

    for (size_t i = 0; i != queryCount; ++ i) {
        u32 type;
        in >> type;

        if (type == 0) {
            size_t left, right;
            in >> left >> right;
            -- left, -- right;

            out << query(left, right + 1, 0, 0, numberCount);
            out.put('\n');
        } else {
            size_t index;
            u32 newValue;

            in >> index >> newValue;
            -- index;

            update(index, newValue, 0, 0, numberCount);
        }
    }
}