Cod sursa(job #3155210)

Utilizator patrick_burasanPatrick Burasan patrick_burasan Data 7 octombrie 2023 17:38:39
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.71 kb
#include <fstream>
#include <vector>
typedef long long ll;

/**
* Classes that speed up the I/O streams
*/

class InParser {
private:
    std::vector<char> str;
    int ptr;
    std::ifstream fin;

private:
    char get_char() {
        if (ptr == (int)str.size()) {
            fin.read(str.data(), (int)str.size());
            ptr = 0;
        }

        return str[ptr++];
    }

    template<class T>
    T get_int() {
        char chr;
        do {
            chr = get_char();
        } while (!isdigit(chr) && (chr != '-'));

        int sgn = +1;
        if (chr == '-') {
            sgn = -1;
            chr = get_char();
        }

        T num = 0;
        while (isdigit(chr)) {
            num = num * 10 + (chr - '0');
            chr = get_char();
        }

        return sgn * num;
    }

public:
    explicit InParser(const char *name) : str((int)1e5), ptr((int)str.size()), fin(name) { }
    ~InParser() { fin.close(); }

    template<class T>
    friend InParser &operator >> (InParser &in, T &num) {
        num = in.get_int<T>();
        return in;
    }
};

class OutParser {
private:
    std::vector<char> str;
    int ptr;
    std::ofstream fout;

private:
    void put_char(char chr) {
        if (ptr == (int)str.size()) {
            fout.write(str.data(), (int)str.size());
            ptr = 0;
        }

        str[ptr++] = chr;
    }

    template<class T>
    void put_int(T num) {
        if (num < 0) {
            put_char('-');
            num *= -1;
        }

        if (num > 9)
            put_int(num / 10);
        put_char(num % 10 + '0');
    }

public:
    explicit OutParser(const char *name) : str((int)1e5), ptr(0), fout(name) { }
    ~OutParser() { fout.write(str.data(), ptr); fout.close(); }

    template<class T>
    friend OutParser &operator << (OutParser &out, const T num) {
        out.put_int(num);
        return out;
    }

    friend OutParser &operator << (OutParser &out, const char chr) {
        out.put_char(chr);
        return out;
    }

    friend OutParser &operator << (OutParser &out, const char *str_arr) {
        for (int i = 0; str_arr[i]; i++)
            out.put_char(str_arr[i]);
        return out;
    }
};

/**
* CLass that builds the Fenwick Tree
*/

class FenwickTree {
private:
    std::vector<ll> bit;
    int n;

    ll query(int i) {
        ll s = 0;
        while (i > 0) {
            s += bit[i];
            i -= i & -i;
        }
        return s;
    }

public:
    explicit FenwickTree(int _n) : n(_n) {
        bit.assign(n + 1, 0);
    }
    ~FenwickTree() = default;

    void update(int i, int delta) {
        while (i <= n) {
            bit[i] += delta;
            i += i & -i;
        }
    }

    ll sum(int l, int r) {
        return query(r) - query(l - 1);
    }

    int get_k(ll target) {
        int st, dr, mid, p = -1;
        st = 1;
        dr = n;
        while (st <= dr) {
            mid = (st + dr) >> 1;
            ll s = query(mid);

            if (s == target) {
                p = mid;
                dr = mid - 1;
            }
            else if (s > target)
                dr = mid - 1;
            else
                st = mid + 1;
        }
        return p;
    }
};

int n, m, val;

int main() {
    InParser cin("aib.in");
    OutParser cout("aib.out");

    cin >> n >> m;
    FenwickTree ft(n);

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

    while (m--) {
        int op, a, b;
        cin >> op;
        if (op == 0) {
            cin >> a >> b;
            ft.update(a, b);
        }
        else if (op == 1) {
            cin >> a >> b;
            cout << ft.sum(a, b) << '\n';
        }
        else {
            cin >> a;
            cout << ft.get_k(a) << '\n';
        }
    }
    return 0;
}