Cod sursa(job #3154747)

Utilizator mihaiBoantaMihai Boanta mihaiBoanta Data 5 octombrie 2023 21:58:27
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.42 kb
#include<iostream>
#include<fstream>
using namespace std;

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

#define nmax 1000000



int msb(int x){
    int msb=1;
    while(x){
        x=x>>1;
        msb=msb<<1;
    }
    return msb;
}
int lsb(int x){
    return x&(-x);
}


int v[nmax];
void build(int n){
    for(int i=1;i<n;i++){
        v[i+lsb(i)]+=v[i];
    }
}
void update(int loc,int val,int n){
    while(loc<n){
        v[loc]+=val;
        loc+=lsb(loc);
    }
}
int query(int now,int stq,int drq){
    int part1=0,part2=0;

    int idx=stq-1;
    while(idx>0){
        part1+=v[idx];
        idx-=lsb(idx);
    }

    idx=drq;
    while(idx>0){
        part2+=v[idx];
        idx-=lsb(idx);
    }

    return part2-part1;
}
int search(int n,int sum){
    int layer=msb(n)/2;
    for(int i=0;layer>0;layer>>=1){
        if(v[i+layer]<=sum && i+layer<=n){
            i+=layer;
            sum-=v[i];
            if(sum==0){
                return i;
            }
        }
    }
    return -1;
}

int main()
{
    int orgN;
    int n,m;
    in>>n>>m;
    for(int i=1;i<=n;i++){
        in>>v[i];
    }
    orgN=n;
    n=msb(n);
    build(n);
    
    int a,b,c;
    for(int i=0;i<m;i++){
        in>>c;
        if(c==0){
            in>>a>>b;
            update(a,b,n);
        }else if(c==1){
            in>>a>>b;
            out<<query(1,a,b)<<'\n';
        }else{
            in>>a;
            out<<search(orgN,a)<<"\n";
        }
    }
}