Cod sursa(job #2334293)

Utilizator igsifvevc avb igsi Data 2 februarie 2019 14:44:47
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.94 kb
#include <algorithm>
#include <fstream>
#include <iterator>
#include <vector>

struct BIT
{
    std::vector<int> bit;

    BIT(const std::vector<int> &V) : bit(V.size() + 1, 0)
    {
        for (size_t i = 0; i < V.size(); ++i)
        {
            this->update(i + 1, V[i]);
        }
    }

    void update(int index, const int value);
    int prefixSum(int index) const;
    int find(const int sum) const;
};

std::vector<int> read(std::istream &in);

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

    std::vector<int> V = read(fin);
    BIT bit(V);

    int op, a, b;
    while (fin >> op >> a)
    {
        switch (op)
        {
        case 0:
            fin >> b;
            bit.update(a, b);
            break;
        case 1:
            fin >> b;
            fout << (bit.prefixSum(b) - bit.prefixSum(a - 1)) << '\n';
            break;
        default:
            fout << bit.find(a) << '\n';
        }
    }

    return 0;
}

inline int lsone(const int x) { return (x ^ (x - 1)) & x; }

void BIT::update(int index, const int value)
{
    do
    {
        this->bit[index] += value;
        index += lsone(index);
    } while (index < this->bit.size());
}

int BIT::prefixSum(int index) const
{
    int sum{0};
    do
    {
        sum += this->bit[index];
        index -= lsone(index);
    } while (index > 0);
    return sum;
}

int BIT::find(const int sum) const
{
    int i{0}, step{1}, N{this->bit.size()}, S{sum};

    for (step = 1; step < N; step <<= 1)
        ;

    for (i = 0; step; step >>= 1)
    {
        if (i + step < N && this->bit[i + step] <= S)
        {
            S -= this->bit[i + step];
            i += step;

            if (S == 0)
                return i;
        }
    }

    return -1;
}

std::vector<int> read(std::istream &in)
{
    int n, throw_away;
    in >> n >> throw_away;

    std::vector<int> V;
    std::copy_n(std::istream_iterator<int>(in), n, std::back_inserter(V));

    return V;
}