Cod sursa(job #2054025)

Utilizator mlc_oficialBoris Barca mlc_oficial Data 1 noiembrie 2017 17:28:17
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.53 kb
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <iostream>
#include <vector>
#include <fstream>

using namespace std;

template<typename T>
class FenwickTree {
public:
    FenwickTree(const int n = 0) : tree(n) { }
    FenwickTree(vector<T>& vals) {
        const int n = (int)vals.size();
        tree = move(vals);
        for (int i = 0; i < n; i += 1) {
            if ((i | (i + 1)) < n) {
                tree[i | (i + 1)] += tree[i];
            }
        }
    }
    
    void Add(int idx, const T& value) {
        for (; idx < (int)tree.size(); idx |= idx + 1) {
            tree[idx] += value;
        }
    }
    
    T Query(int idx) const {
        T r = 0;
        for (; idx >= 0; idx = (idx & (idx + 1)) - 1) {
            r += tree[idx];
        }
        return r;
    }
    
    T Query(int left, int right) const { 
        return Query(right) - Query(left - 1); 
    }
    
    T FindValue(int idx) const {
        T r = tree[idx];
        if (idx > 0) {
            const int lca = (idx & (idx + 1)) - 1;
            for (--idx; idx != lca; idx = (idx & (idx + 1)) - 1) {
                r -= tree[idx];
            }
        }
        return r;
    }
    
    void Set(int idx, const T& new_value) {
        Add(idx, -FindValue(idx) + new_value);
    }
    
    int LowerBound(T sum) const {
        --sum;
        int idx = -1;
        for (int step = 1 << __lg(tree.size()); step; step >>= 1) {
            if (idx + step < (int)tree.size() and tree[idx + step] <= sum) {
                idx += step;
                sum -= tree[idx];
            }
        }
        return idx + 1;
    }
private:
    vector<T> tree; 
};

int main() {
    ifstream cin("aib.in");
    ofstream cout("aib.out");
    
    int n, q; cin >> n >> q;
    vector<int> values(n);
    for (auto& x : values) { 
        cin >> x;
    }
    
    FenwickTree<int> fen(values);
    while (q--> 0) {
        int type; cin >> type;
        if (type == 0) {
            int idx, value; cin >> idx >> value; idx -= 1;
            fen.Add(idx, value);
        } else if (type == 1) {
            int left, right; cin >> left >> right; left -= 1; right -= 1;
            cout << fen.Query(left, right) << '\n';
        } else {
            int prefix_sum; cin >> prefix_sum;
            const int result = fen.LowerBound(prefix_sum);
            
            if (fen.Query(result) != prefix_sum) {
                cout << "-1\n";
            } else {
                cout << 1 + result << '\n';
            }
        }
    }
}