Cod sursa(job #2865304)

Utilizator the_horoHorodniceanu Andrei the_horo Data 8 martie 2022 18:20:00
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.01 kb
#include <cstdint>
#include <fstream>
#include <iostream>
#include <vector>


/* Defines */
using i32 = int32_t;
using u32 = uint32_t;

template<typename IntT>
class BinaryIndexedTreeSum {
public:
    BinaryIndexedTreeSum (const std::vector<IntT> &data): m_data(data.size() + 1) {
        for (size_t i = 0; i != data.size(); ++ i)
            update(i + 1, data[i]);
    }

    /* All the queries take 1 indexed values */

    /* It computes the sum up to and including `index` */
    IntT sumUntil (size_t index) const {
        IntT result = 0;
        for (; index != 0; index -= lastBit(index))
            result += m_data[index];
        return result;
    }

    /* Calculates the sum of the values [left, right] */
    IntT sumBetween (size_t left, size_t right) const {
        return sumUntil(right) - sumUntil(left - 1);
    }

    void update (size_t position, IntT delta) {
        for (; position < m_data.size(); position += lastBit(position))
            m_data[position] += delta;
    }

    size_t lowerBound (IntT value) const {
        size_t i;
        for (i = 1; i < m_data.size(); i <<= 1) {}

        size_t result = 0;
        IntT soFar = 0;
        for (i >>= 1; i != 0; i >>= 1) {
            if (result + i < m_data.size() && soFar + m_data[result + i] < value) {
                result += i;
                soFar += m_data[result];
            }
        }

        result += (soFar < value);

        return result;
    }
private:
    static size_t lastBit (size_t value) {
        return value & (-value);
    }

    void debugData (const char *title) const {
        std::clog << title << '\n';
        for (auto val: m_data)
            std::clog << val << ' ';
        std::clog << std::endl;
    }

    std::vector<IntT> m_data;
};

constexpr const char *inputFilename = "aib.in";
constexpr const char *outputFilename = "aib.out";


int main () {
    std::ifstream input(inputFilename);
    input.exceptions(input.badbit | input.eofbit | input.failbit);
    std::ofstream output(outputFilename);
    input.exceptions(output.badbit | output.eofbit | output.failbit);

    size_t valueCount;
    u32 queries;
    input >> valueCount >> queries;

    std::vector<u32> values(valueCount);
    for (auto &value: values)
        input >> value;
    BinaryIndexedTreeSum<u32> sums(values);

    for (u32 q = 0; q != queries; ++ q) {
        u32 type;
        input >> type;

        if (type == 0) {
            size_t index;
            u32 delta;
            input >> index >> delta;

            sums.update(index, delta);
        } else if (type == 1) {
            size_t left, right;
            input >> left >> right;

            output << sums.sumBetween(left, right) << '\n';
        } else if (type == 2) {
            u32 sum;
            input >> sum;

            const size_t position = sums.lowerBound(sum);

            if (position != 0 && position <= valueCount && sums.sumUntil(position) == sum)
                output << position;
            else
                output << "-1";
            output.put('\n');
        }
    }
}