Cod sursa(job #2206094)

Utilizator whoiscrisCristian Plop whoiscris Data 21 mai 2018 01:40:07
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.83 kb
#include <bits/stdc++.h>
using namespace std;
 
#define NMAX        100009
#define MMAX        200009
#define kInf        (1 << 30)
#define kInfLL      (1LL << 60)
#define kMod        666013
#define edge pair<int, int>
#define x first
#define y second
 
#define USE_FILES "MLC"
 
#ifdef USE_FILES
#define cin fin
#define cout fout
ifstream fin("aib.in");
ofstream fout("aib.out");
#endif
 
// number of tests from "in"
int test_cnt = 1;
void clean_test();
 
// your global variables are here
 
// Binary Indexed Trees
template<typename T = int>
struct BIT {
    // UPDATE      UPDATE
    // PREFIX_SUM  SUM[1, ..., k]
    // QUERY       SUM[i, j]
    // FIND_K      SUM[1...k] == S
    #define LSB(x) ((-x) & x)
 
    int size;
    vector<T> bit; // bit[0], bit[1], ..., bit[size]
 
    // because size is fixed, I can precompute STEP_MAX for FIND_K
    int STEP_MAX;
 
    BIT(int _size) : size(_size), bit(_size + 1, 0) {
        // precompute max_step
        STEP_MAX = 1;
        while (STEP_MAX < size) {
            STEP_MAX <<= 1;
        }
    }
 
    void update(int k, const T& x) {
        for(;  k <= size;  k += LSB(k)) {
            bit[k] += x;
        }
    }
 
    int prefix_sum(int k) {
        T sum = 0;
 
        for(; k > 0; k -= LSB(k)) {
            sum += bit[k];
        }
 
        return sum;
    }
 
    T query(const int &i, const int &j) {
        return prefix_sum(j) - prefix_sum(i - 1);
    }
 
    int find_k(T sum) {
        int k = 0;
 
        for (int step(STEP_MAX); step > 0; step >>= 1) {
            if (k + step <=  size && bit[k + step] <= sum) {
                k += step;
                sum -= bit[k];
 
                if (sum == 0) {
                    return k;
                }
            }
        }
 
        return -1;
    }
};
 
// your solution is here
void solve() {
    int n, Q;
    cin >> n  >> Q;
 
    BIT<int> bit(n + 1);
    vector<int> v(n + 1);
 
    for (int i = 1; i <= n; ++i) {
        int x;
        cin >> x;
 
        bit.update(i, x);
    }
 
    while (Q--) {
        int type, start, end, x, pos;
        cin >> type;
 
        switch (type) {
            case 0: {
                cin >> pos >> x;
                bit.update(pos, x);
                v[pos] = x;
 
                break;
            }
 
            case 1: {
                cin >> start >> end;
                cout << bit.query(start, end) << "\n";
 
                break;
            }
 
 
            case 2: {
                fin >> x;
                fout << bit.find_k(x) << "\n";
 
                break;
            }
 
            default: {
                fout << "wtf?";
                break;
            }
        }
    }
 
 
    if (test_cnt > 0) {
        clean_test();
    }
}
 
 
void clean_test() {
    // clean if needed
}
 
 
int main() {
//     cin >> test_cnt;
    while (test_cnt--) {
        solve();
    }
 
    return 0;
}