Cod sursa(job #3156574)

Utilizator xXoctavianXxStanescu Matei Octavian xXoctavianXx Data 11 octombrie 2023 19:46:25
Problema Arbori indexati binar Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.61 kb
#include <bits/stdc++.h>

using namespace std;

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

const int nmax = 1e5+5;
int a[nmax];

struct SegTree {
    int nextPowOf2(int n)
    {
        int p =1;
        while(p<=n) p*=2;
        return p;
    }

    vector<int> aint;
    int offset;

    SegTree (int n)
    {
        offset = nextPowOf2(n);
        aint.resize(2*offset + 1);
    }

    void update(int pos, int change)
    {
        aint[pos + offset] += change;
        for(pos = (pos + offset) / 2; pos > 0; pos/=2)
        {
            aint[pos] = aint[2* pos] + aint[2*pos + 1];
        }
    }

    int _query(int node, int l, int r, int gl, int gr)
    {
        if(r < gl || gr < l) return 0;
        if(gl <= l && r <= gr)
        {
            return aint[node];
        }

        int mij = (l+r) /2;
        return _query(2*node, l,mij,gl,gr) + _query(2*node + 1, mij+1,r,gl,gr);
    }

    int query(int l, int r)
    {
        return _query(1,0,offset-1,l,r);
    }

    int cautBin(int node, int l, int r, int gl, int target, int &suma)
    {
        if(r < gl) return r;
        if(suma + aint[node] <= target)
        {
            suma += aint[node];
            return r;
        }
        ///de aici incolo, nu am putut include tot intervalul
        if(l == r) return l-1;

        int mij = (l+r)/2;
        int stanga = cautBin(2*node,l,mij,gl,target,suma);
        if(stanga < mij)
        {
            return stanga;
        }
        if(stanga == mij)
        {
            ///atentie, suma s-a updatat cand am apelat int stanga = cautBin(...), deci nu mai e
            ///nevoie sa o mai updatez
            return cautBin(2*node + 1, mij+1,r,gl,target,suma);
        }
    }

    int cb_fast(int target) //gl e mereu 1
    {
        int suma = 0;
        int capat_right = cautBin(1,0,offset-1,1,target,suma);
        if(suma == target) return capat_right;
        else return -1;
    }
};

int main()
{
    int n,m; fin>>n>>m;
    SegTree st = SegTree(n);
    for(int i=1; i<=n; i++)
    {
        fin>>a[i];
        st.update(i,a[i]);
    }
    for(int i=0; i<m; i++)
    {
        int type; fin>>type;
        if(type == 0)
        {
            int a,b; fin>>a>>b;
            st.update(a,b);
        }
        else if(type == 1)
        {
            int a,b; fin>>a>>b;
            fout<<st.query(a,b)<<"\n";
        }
        else
        {
            int a; fin>>a;
            int rasp = st.cb_fast(a);
            if(rasp > n) rasp = n;
            fout<<rasp<<"\n";
        }
    }
    return 0;
}