Cod sursa(job #3136934)

Utilizator Alex18maiAlex Enache Alex18mai Data 9 iunie 2023 13:54:39
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.68 kb
// Alexandru Enache

#include <fstream>
#include <vector>
#include <math.h>

using namespace std;

ifstream cin("aib.in"); ofstream cout("aib.out");


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){
    v[pos] += 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 + v[pos+1] != val){
        return -1;
    }
    return pos+1;
}


int main() {

    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;
}