Cod sursa(job #1612882)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 25 februarie 2016 08:33:10
Problema Arbori indexati binar Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 2.15 kb
#include <iostream>
#include <vector>
#include <cmath>
#include <fstream>
using namespace std;

class arbint{
    int n;
    vector<int> buf;
    int right_child_all_the_way_down(int x){
        for( ; x < n; x = 2*x+1);
        return x;
    }
public:
    arbint(const vector<int>& v): n(1<<(int)ceil(log2(v.size()))), buf(2*n, 0){
        copy(v.begin(), v.end(), buf.begin() + n);
        for(int i = v.size()+n; i < 2*n; ++i){
            buf[i] = 1;
        }
        for(int i = n-1; i > 0; --i){
            buf[i] = buf[2*i] + buf[2*i+1];
        }
    }
    void update(int p, const int v){
        for(p += n; p > 0; p /= 2){
            buf[p] += v;
        }
    }
    int query(int st, int dr){
        int rez = 0;
        for(st += n, dr += n+1; st < dr; st /= 2, dr /= 2){
            if(st%2 == 1){
                rez += buf[st++];
            }
            if(dr%2 == 1){
                rez += buf[--dr];
            }
        }
        return rez;
    }
    int search(const int k){
        int sum_st = 0, p = 1;
        while(p < n){
            if(sum_st + buf[2*p] < k){
                sum_st += buf[2*p];
                p = 2*p+1;
            }
            else if(sum_st + buf[2*p] == k){
                return right_child_all_the_way_down(2*p)-n;
            }
            else{
                p *= 2;
            }
        }
        if(sum_st + buf[p] == k){
            return p-n;
        }
        return -2;
    }
};

int main()
{
    ifstream f("aib.in");
    ofstream g("aib.out");
    int n, m;
    f >> n >> m;
    vector<int> v(n);
    for(int i = 0; i < n; ++i){
        f >> v[i];
    }
    arbint arb(v);
    for(int i = 0, t, a, b, k; i < m; ++i){
        f >> t;
        if(t == 0){
            f >> a >> b;
            arb.update(a-1, b);
        }
        else if(t == 1){
            f >> a >> b;
            g << arb.query(a-1, b-1) << '\n';
        }
        else{
            f >> k;
            const int rez = arb.search(k)+1;
            if(rez > n){
                g << -1 << '\n'; }
            g << rez << '\n';
        }
    }

    return 0;
}