Cod sursa(job #2462298)

Utilizator preda.andreiPreda Andrei preda.andrei Data 26 septembrie 2019 23:52:49
Problema Arbori indexati binar Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.6 kb
#include <fstream>
#include <vector>

using namespace std;

class Bit
{
public:
    Bit(int size) : bit_(size + 2, 0) {}

    void Add(int pos, int value);

    int Sum(int right) const;
    int Sum(int left, int right) const { return Sum(right) - Sum(left - 1); }

    int Prefix(int sum) const;

private:
    static int Lsb(int num) { return num & -num; }

    vector<int> bit_;
};

void Bit::Add(int pos, int value)
{
    while (pos < (int)bit_.size()) {
        bit_[pos] += value;
        pos += Lsb(pos);
    }
}

int Bit::Sum(int right) const
{
    int sum = 0;
    while (right > 0) {
        sum += bit_[right];
        right -= Lsb(right);
    }
    return sum;
}

int Bit::Prefix(int sum) const
{
    int pos = -1;
    int pow = (1 << 25);

    while (pow > 0) {
        int next_pos = pos + pow;
        pow >>= 1;

        if (next_pos < (int)bit_.size() && Sum(next_pos) < sum) {
            pos = next_pos;
        }
    }

    pos += 1;
    return (pos < (int)bit_.size() && Sum(pos) == sum) ? pos : -1;
}

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

    int n, ops;
    fin >> n >> ops;

    Bit bit(n);
    for (int i = 1; i <= n; i += 1) {
        int num;
        fin >> num;
        bit.Add(i, num);
    }

    for (int i = 1; i <= ops; i += 1) {
        int type, a, b;
        fin >> type;

        if (type == 0) {
            fin >> a >> b;
            bit.Add(a, b);
        } else if (type == 1) {
            fin >> a >> b;
            fout << bit.Sum(a, b) << "\n";
        } else {
            fin >> a;
            fout << bit.Prefix(a) << "\n";
        }
    }
    return 0;
}