Cod sursa(job #2482853)

Utilizator theo2003Theodor Negrescu theo2003 Data 28 octombrie 2019 22:32:28
Problema Arbori indexati binar Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.14 kb
#include <fstream>
using namespace std;
ifstream cin("aib.in");
ofstream cout("aib.out");
struct aint {
    aint *a, *b, *p;
    int l, r;
    int v;
    aint(aint *x, int y, int z) {
        p = x;
        l = y;
        r = z;
    }
    aint(){}
};
int ls[1000001];
aint *leaf[1000001];
aint root;
int build(aint *node) {
    int l = node->l;
    int r = node->r;
    if(l == r) {
        node->v = ls[l];
        leaf[node->l] = node;
        return node->v;
    } else {
        node->a = new aint(node, l, l + (r - l + 1)/2 - 1);
        node->b = new aint(node, l + (r - l + 1)/2, r);
        return node->v = build(node->a) + build(node->b);
    }
}
int query(aint *node, int l, int r) {
    if((l == node->l) && (r == node->r))
        return node->v;
    else if(r <= node->a->r)
        return query(node->a, l, r);
    else if(l >= node->b->l)
        return query(node->b, l, r);
    else return query(node->a, l, node->a->r) + query(node->b, node->b->l, r);
}
void add(aint *node, int add){
    while(true){
        node->v += add;
        if(node->p == NULL)
            return;
        node = node->p;
    }
}
int main() {
    int n, m;
    cin>>n>>m;
    for(int x = 1; x<=n; x++)
        cin>>ls[x];
    root = aint(NULL, 1, n);
    build(&root);
    for(int x = 0, req;x<m;x++){
        cin>>req;
        if(req == 0){
            int target, add_;
            cin>>target>>add_;
            add(leaf[target], add_);
        }else if(req == 1){
            int l, r;
            cin>>l>>r;
            cout<<query(&root, l, r)<<'\n';
        }else{
            int v;
            cin>>v;
            int l = 1, r = n, m;
            while(l != r){
                m = l + (r - l)/2;
                int v1 = query(&root, 1, m);
                if(v1 == v){
                    l = m;
                    r = m;
                    break;
                }else if(v1 < v){
                    l = m + 1;
                }else r = m - 1;
            }
            m = l;
            if(query(&root, 1, m) != v)
                cout<<-1<<'\n';
            else cout<<l<<'\n';
        }
    }
}