Cod sursa(job #3303377)

Utilizator livliviLivia Magureanu livlivi Data 15 iulie 2025 13:05:33
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.8 kb
#include <iostream>
#include <vector>

#define lsb(x) (x & (-x))

using namespace std;

struct AIB {
    vector<long long> aib;

    AIB(int n) {
        aib.resize(n + 1);
    }

    void update(int k, int add)
    {
        for(int i = k; i < aib.size(); i += lsb(i))
        {
            aib[i] += add;
        }
    }

    long long query(int x)
    {
        if (x >= aib.size()) {
            return -1;
        }
        long long sum = 0;
        for(int i = x; i > 0; i -= lsb(i)){
            sum += aib[i];
        }
        return sum;
    }

    int cbin(long long s, bool strict = false) {
        int ans = 0;
        long long sum_ans = 0;

        for (int pas = (1 << 18); pas > 0; pas /= 2) {
            if (ans + pas >= aib.size()) { continue; }
            if (sum_ans + aib[ans + pas] + strict <= s) {
                ans += pas;
                sum_ans += aib[ans];
            }
        }

        return ans;
    }
};

int main() {
#ifndef LOCAL
    freopen("aib.in", "r", stdin);
    freopen("aib.out", "w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    int n, q; cin >> n >> q;
    AIB aib(n);

    for (int i = 1; i <= n; i++) {
        int x;
        cin >> x;
        aib.update(i, x);
    }

    for (int i = 1; i <= q; i++) {
        int type; cin >> type;
        if (type == 0) {
            int a, b; cin >> a >> b;
            aib.update(a, b);
        } else if (type == 1) {
            int a, b; cin >> a >> b;
            cout << aib.query(b) - aib.query(a - 1) << "\n";
        } else {
            long long s; cin >> s;
            int pos = aib.cbin(s, /* strict= */ true) + 1;
            if (aib.query(pos) == s) {
                cout << pos << "\n";
            } else {
                cout << "-1\n";
            }
        }
    }

    return 0;
}