Cod sursa(job #3267193)

Utilizator IleaIlea Bogdan Ilea Data 11 ianuarie 2025 10:18:34
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.86 kb
// aib -> size==n
// conteaza ultimul bit de 1 al indexului
// i&-i se inverseaza toti si se pastreaza numai cel mai din dreapta bit de 1 
// i=10110100, -i=01001100
// i-=(i&-i) (query) sau i+=(i&-i) (update)
// pt query tot facem operatia aia ca sa scadem cu intervale
// pt update ttot facem operatitia pt a inainta in toate multimile in care se foloseste elementul x

#include <iostream>

using namespace std;
#define endl '\n'
int aib[100001], n, m, op, x, y;
void update(int ind, int x){
    for (int i=ind; i<=n; i+=(i&-i)){
        aib[i]+=x;
    }
}
int query(int ind){
    int sum=0;
    for (int i=ind; i>=1; i-=(i&-i)){
        sum+=aib[i];
    }
    return sum;
}
int main(){
    freopen("aib.in", "r", stdin);
    scanf("%d%d", &n, &m);
    for (int i=1; i<=n; ++i){
        scanf("%d", &x);
        update(i, x);
    }
    freopen("aib.out", "w", stdout);
    for (int im=0; im<m; ++im){
        scanf("%d", &op);
        //cout<<op<<endl;
        if (op==0){
            // cerinta 0
            scanf("%d%d", &x, &y);
            update(x, y);
        } else if (op==1){
            // cerinta 1
            scanf("%d%d", &x, &y);
            cout<<query(y)-query(x-1)<<endl;
        } else {
            // cerinta 2
            scanf("%d", &x);
            
            // un fel de cautare binara pana la ce iti trebe
            
            bool ok=true;
            int st=1, dr=n;
            while (st<=dr){
                int mij=(st+dr)/2, q=query(mij);
                if (q==x){
                    cout<<mij<<endl;
                    ok=false;
                    break;
                } else if (x<q){
                    dr=mij-1;
                } else {
                    st=mij+1;
                }
            }
            if (ok){
                cout<<"-1\n";
            }
        }
    }
}