Cod sursa(job #3156565)

Utilizator Botnaru_VictorBotnaru Victor Botnaru_Victor Data 11 octombrie 2023 19:32:32
Problema Arbori indexati binar Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.03 kb
#include <bits/stdc++.h>

using namespace std;

#define FIO

#ifdef FIO

ifstream in("aib.in");
ofstream out("aib.out");
#define cin in
#define cout out
#endif // FIO



int nextbit(int n)
{
    int p=1;
    while(p<n) p<<=1;
    return p;
}

struct arbint{
    int offset;
    vector<int> arb;

    arbint (int n){
        offset=nextbit(n);
        arb.assign(offset*2,0);
    }

    void update(int poz,int x)
    {
        for(poz+=offset-1;poz>0;poz>>=1)
        {
            arb[poz]+=x;
        }
    }

    int query(int st, int dr)
    {
        int ans=0;
        for(st+=offset-1, dr+=offset; st<dr; st>>=1, dr>>=1){
            if(st&1) ans+=arb[st++];
            if(dr&1)ans+=arb[--dr];
        }
        return ans;
    }

    int cb(int nod,int st, int dr, int qst, int &suma)
    {
        if(dr<qst) return dr;

        if(st==dr&&suma<arb[nod])
        {
            return st-1;
        }

        if(qst<=st && suma>=arb[nod])
        {
            suma-=arb[nod];
            return dr;
        }


        int mid=(st+dr)/2;
        int cb_stanga=cb(nod*2,st,mid, qst,suma);
        if(cb_stanga<mid)
        {
            return cb_stanga;
        }
        return cb(nod*2+1,mid+1,dr,qst,suma);
    }

    int caut(int st, int suma)
    {
        return cb(1,1,offset,st,suma);
    }

};


int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n,m;
    cin>>n>>m;
    arbint arb(n);

    int a,b,c;

    for(int i=1;i<=n;i++)
    {
        cin>>a;
        arb.update(i,a);
    }
    for(int i=1;i<=m;i++)
    {
        cin>>c;
        switch(c)
        {
        case 0:
            cin>>a>>b;
            arb.update(a,b);
            break;
        case 1:
            cin>>a>>b;
            cout<<arb.query(a,b)<<'\n';
            break;
        case 2:
            cin>>a;
            cout<<arb.caut(1,a)<<'\n';
            break;
        default:
            assert(0);
        }
    }
    return 0;
}