Cod sursa(job #3136931)

Utilizator Alex18maiAlex Enache Alex18mai Data 9 iunie 2023 13:45:38
Problema Arbori indexati binar Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.71 kb
// Alexandru Enache

#include <bits/stdc++.h>

using namespace std;

int LSB(int i){
    return (i & (-i));
}

int n, m;
vector<int> v;
vector<int> aib;

void init(){
    for (int i=1; i<=n; i++){
        aib[i] += v[i];
        if (i+LSB(i) <= n){
            aib[i+LSB(i)] += aib[i];
        }
    }
}

void update(int pos, int val){
    for (int i=pos; i<=n; i+=LSB(i)){
        aib[i] += val;
    }
}

int queryPrefix(int pos){
    int sum = 0;
    for (int i=pos; i>0; i-=LSB(i)){
        sum += aib[i];
    }
    return sum;
}

int queryInterval(int a, int b){
    return queryPrefix(b) - queryPrefix(a-1);
}

int searchPrefix(int val){
    int sum = 0;
    int pos = 0;

    for (int bit=int(log2(n)); bit>=0; bit--){
        if (pos + (1 << bit) > n){
            continue;
        }
        if (sum + aib[pos + (1 << bit)] <= val){
            pos += (1 << bit);
            sum += aib[pos];
        }
    }

    if (sum != val){
        return -1;
    }
    return pos;
}


int main() {

    // freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
    freopen("aib.in", "r", stdin); freopen("aib.out", "w", stdout);

    cin>>n>>m;

    v.resize(n+1);
    aib.resize(n+1, 0);

    for (int i=1; i<=n; i++){
        cin>>v[i];
    }

    init();

    for (int i=1; i<=m; i++){
        int t;
        cin>>t;

        if (t == 0){
            int pos, val;
            cin>>pos>>val;
            update(pos, val);
        }
        else if (t == 1){
            int a, b;
            cin>>a>>b;
            cout << queryInterval(a, b) << '\n';
        }
        else if (t == 2){
            int val;
            cin>>val;
            int ans = searchPrefix(val);
            cout<<ans<<'\n';
        }
    }

    return 0;
}