Cod sursa(job #2940590)

Utilizator preda.andreiPreda Andrei preda.andrei Data 15 noiembrie 2022 21:23:54
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.74 kb
#include <fstream>
#include <vector>

using namespace std;

struct Fenwick {
    vector<int> nodes;

    Fenwick(int size) : nodes(size + 1, 0) {
    }

    void Add(int pos, int val) {
        while (pos < (int)nodes.size()) {
            nodes[pos] += val;
            pos += Lsb(pos);
        }
    }

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

    int Get(int prefix) const {
        auto sum = 0;
        while (prefix > 0) {
            sum += nodes[prefix];
            prefix -= Lsb(prefix);
        }
        return sum;
    }

    int Size() const {
        return nodes.size() - 1;
    }

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

int FindMinPrefix(const Fenwick& fen, int sum) {
    auto pos = 0;
    for (auto pow = 1 << 30; pow > 0; pow >>= 1) {
        auto next = pos + pow;
        if (next <= fen.Size() && fen.Get(next) < sum) {
            pos = next;
        }
    }
    if (fen.Get(pos + 1) == sum) {
        return pos + 1;
    }
    return -1;
}

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

    int n, queries;
    fin >> n >> queries;

    Fenwick fen(n);
    for (int i = 0; i < n; i += 1) {
        int num;
        fin >> num;
        fen.Add(i + 1, num);
    }

    for (int i = 0; i < queries; i += 1) {
        int type;
        fin >> type;

        if (type == 0) {
            int pos, val;
            fin >> pos >> val;
            fen.Add(pos, val);
        } else if (type == 1) {
            int left, right;
            fin >> left >> right;
            fout << fen.Get(left, right) << "\n";
        } else {
            int sum;
            fin >> sum;
            fout << FindMinPrefix(fen, sum) << "\n";
        }
    }
    return 0;
}