Cod sursa(job #2592936)

Utilizator cip_ionescuCiprian Ionescu cip_ionescu Data 2 aprilie 2020 16:51:46
Problema Range minimum query Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.75 kb
#include <iostream>
#include <fstream>
#include <limits>
#include <array>

using std::cin;
using std::cout;

constexpr unsigned log2(unsigned x) {
    return x == 1 ? 0 : 1 + log2(x >> 1);
}

constexpr unsigned LSB(unsigned x) {
    return x & (-x);
}

template <typename T, size_t N>
class BITree {
public:
    typedef typename std::array<T, N>::size_type size_type;
    typedef typename std::numeric_limits<T> value_limits;

private:
    std::array<T, N> bit;
    size_type size = 0;

public:
    void resize(const size_type n) {
        size = n;
    }

    T query(size_type p) {
        T s = 0;
        for ( ; p > 0 ; p -= LSB(p))
            s += bit[p];
        return s;
    }

    void update(size_type p, const T val) {
        for ( ; p <= size ; p += LSB(p))
            bit[p] += val;
    }

    T search(T x) {
        if (!x) return -1;

        size_type p = 0, pas = 1 << log2(N);

        while (pas) {
            if (p + pas <= size && bit[p + pas] <= x) {
                p += pas;
                x -= bit[p];
            }
            pas >>= 1;
        }

        if (x) return -1;
        return p;
    }
};

BITree<int, 100001> t;

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

    int n, m;
    fin >> n >> m;
    t.resize(n);

    for (auto i = 1 ; i <= n ; i++) {
        int x;
        fin >> x;
        t.update(i, x);
    }

    for (auto i = 1 ; i <= m ; i++) {
        int c, a, b;
        fin >> c;
        if (c == 0) {
            fin >> a >> b;
            t.update(a, b);
        }
        if (c == 1) {
            fin >> a >> b;
            fout << t.query(b) - t.query(a - 1) << '\n';
        }
        if (c == 2) {
            fin >> a;
            fout << t.search(a) << '\n';
        }
    }
    
    return 0;
}