Cod sursa(job #2868468)

Utilizator the_horoHorodniceanu Andrei the_horo Data 10 martie 2022 22:36:52
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.84 kb
#include <array>
#include <cassert>
#include <cstdint>
#include <fstream>
#include <vector>


using i32 = int32_t;
using u32 = uint32_t;

constexpr size_t MAX_VALUES = 100000;


std::array<u32, MAX_VALUES> arbint;
size_t valueCount;

size_t lastBit (size_t value) {
    return value & (-value);
}

void update (size_t index, u32 delta) {
    for (; index <= valueCount; index += lastBit(index)) {
        arbint[index] += delta;
    }
}

u32 query (size_t upTo) {
    u32 result = 0;
    for (; upTo; upTo -= lastBit(upTo))
        result += arbint[upTo];
    return result;
}

size_t lowerBound (u32 sum) {
    size_t bit;
    for (bit = 1; bit <= valueCount; bit <<= 1) {}

    bit >>= 1;
    size_t result = 0;
    u32 soFar = 0;
    for (; bit; bit >>= 1)
        if (result + bit <= valueCount && soFar + arbint[result + bit] < sum) {
            result += bit;
            soFar += arbint[result];
        }

    return result + (arbint[1] <= sum);
}

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

    in >> valueCount;
    u32 queries;
    in >> queries;

    for (size_t i = 1; i <= valueCount; ++ i) {
        u32 x;
        in >> x;
        update(i, x);
    }

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

        if (type == 0) {
            size_t index;
            u32 value;
            in >> index >> value;

            update(index, value);
        } else if (type == 1) {
            size_t left, right;
            in >> left >> right;

            out << query(right) - query(left - 1) << '\n';
        } else if (type == 2) {
            u32 sum;
            in >> sum;

            const size_t pos = lowerBound(sum);

            if (pos != 0 && pos <= valueCount && query(pos) == sum)
                out << pos << '\n';
            else
                out << "-1\n";
        }
    }
}