Cod sursa(job #3209582)

Utilizator Sabin1133Padurariu Sabin Sabin1133 Data 2 martie 2024 21:33:28
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.4 kb
#include <bits/stdc++.h>

class fenwick {
private:
    std::vector<int> data;
    int sz;

    inline int _lsb(int x)
    {
        return x & -x;
    }

    inline int _psum(int index)
    {
        int sum = 0;

        while (index > 0) {
            sum += this->data[index];
            index -= this->_lsb(index);
        }

        return sum;
    }

public:
    fenwick()
    {
        this->data.push_back(0);
    }

    void add(int val)
    {
        this->data.push_back(val);
    }

    void preprocess()
    {
        int n = this->data.size();

        for (int i = n; i > 0; --i)
            for (int j = 1; j < this->_lsb(i); ++j)
                this->data[i] += this->data[i - j];

        this->sz = n - 1;
    }

    int rangesum(int l, int r)
    {
        return this->_psum(r) - this->_psum(l - 1);
    }

    void update(int index, int val)
    {
        while (index <= this->sz) {
            this->data[index] += val;
            index += this->_lsb(index);
        }
    }

    int first_k_sum(int sum)
    {
        int index, step;

        for (step = 1; (step << 1) <= this->sz; step <<= 1) {}

        for (index = 0; step > 0; step >>= 1) {
            if (index + step <= this->sz && this->data[index + step] <= sum) {
                index += step;
                sum -= this->data[index];

                if (sum == 0)
                    return index;
            }
        }

        return -1;
    }

    int size()
    {
        return this->data.size() - 1;
    }

    void show()
    {
        for (int i = 1; i <= this->sz; ++i)
            std::cout << this->data[i] << ' ';
        std::cout << '\n';
    }
};

int main()
{
    int n, m;
    fenwick tree;

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

    fin >> n >> m;

    for (int x, i = 0; i < n; ++i) {
        fin >> x;
        tree.add(x);
    }

    tree.preprocess();

    tree.show();

    for (int op, arg1, arg2, i = 0; i < m; ++i) {
        fin >> op;

        switch (op) {
        case 0:
            fin >> arg1 >> arg2;
            tree.update(arg1, arg2);
            break;
        case 1:
            fin >> arg1 >> arg2;
            fout << tree.rangesum(arg1, arg2) << '\n';
            break;
        case 2:
            fin >> arg1;
            fout << tree.first_k_sum(arg1) << '\n';
            break;
        default:
            break;
        }
    }

    fin.close();
    fout.close();

    return 0;
}