Cod sursa(job #3267243)

Utilizator IleaIlea Bogdan Ilea Data 11 ianuarie 2025 10:31:28
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.42 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 interx
// 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);
            // mai eficient (cred)
            
            int i, step;
            bool ok=true;
            for (step=1; step<n; step*=2){} 
            for(i=0; step; step/=2){
                if(i+step<=n){
                    if(x>=aib[i+step]){
                        i+=step;
                        x-=aib[i];
                        if (!x){
                            ok=false;
                            break;
                        }
                    }
                }
            }
            if (ok)cout<<"-1\n";
            else cout<<i<<endl;
            
            
            
            // ineficient
            /*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";
            }*/
        }
    }
}