Cod sursa(job #1591248)

Utilizator elevenstrArina Raileanu elevenstr Data 5 februarie 2016 22:23:27
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.06 kb
#include <bits/stdc++.h>

using namespace std;
ifstream in("aib.in");
ofstream out("aib.out");
#define MAX 100008
int n,m,arb[MAX],a,b,x,k;
void update(int poz, int val)
{
     int c=0;
     while(poz<=n)
     {
         arb[poz]+=val;
         while((poz&(1<<c))==0)c++;
         //cautam primul bit care nu e egal cu 0 de la cel mai nesemnificativ
         //si il adaugam la poz.
         //https://www.youtube.com/watch?v=CWDQJGaN1gY
         //ex : 3->4->8->16...
         poz=poz+(1<<c);
         c=c+1;
     }
}
int query(int poz)
{
    int c=0,s=0;
    while(poz>0)
    {
        s=s+arb[poz];
        while((poz&(1<<c))==0)c++;
        poz=poz-(1<<c);
        c=c+1;
    }
     return s;
    /*ex:
    15= 1111
    14= 1110 (tatal lui 15)
    12=1100(tatal lui 14)
    8=1000(tatal lui 12)
    0=0000(tatal lui 8)
    :)
    */
    //pozitiile impare nu au fii
}
int caut(int sum)
{
    int pas=1;
    while(pas<n)
        pas=pas<<1;
    //cea mai mare putere a lui 2 mai mica decat n
    for(int i=0;pas;pas=pas>>1)
    {
        //cat timp pas mai mare decat 0, pas devine pas/2
        if(i+pas<=n)
        {
            if(sum>=arb[i+pas])
            {
                sum=sum-arb[i+pas];
                i=i+pas;
                if(sum==0)return i;
                // ca si cum am cauta bitii de 1 (mai intai gasim baza si pe urma mergem in jos pe arbore :) )
            }
        }
    }
    return -1;
}
int main()
{  in>>n>>m;
for(int i=1;i<=n;i++)
{
    in>>x;
    update(i,x);
    //pe pozitia i (val.=0) se aduna val. b
}
while(m--)
{
    in>>k;
    if(k==0)
    {
        in>>a>>b;
        update(a,b);
        //pe pozitia a se aduna val. b
    }
    if(k==1)
    {
        in>>a>>b;
        out<<query(b)-query(a-1)<<'\n';
        //suma elementelor de la 0 pana la pozitia b - suma el. de la 0 la a-1 (suma el. de la a la b)
    }
    if(k==2)
    {
        in>>a;
        out<<caut(a)<<'\n';
        // pozitia minima k a.i. suma primilor k termeni sa fie a
    }
}

    return 0;
}