Cod sursa(job #2334276)

Utilizator igsifvevc avb igsi Data 2 februarie 2019 14:24:21
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.89 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 k{0}, i{1}, j{this->bit.size()};

    while (i <= j)
    {
        k = i + (j - i) / 2;

        int prefix = this->prefixSum(k);

        if (prefix == sum)
            return k;
        
        if (prefix < sum)
            i = k+1;
        else
            j = k-1;
    }

    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;
}