Cod sursa(job #1199298)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 18 iunie 2014 19:30:12
Problema Arbori indexati binar Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 2.16 kb
#include <cstdio>
#include <cstring>
#include <algorithm>

#define Nmax 100005
#define DIM 666013
char buff[DIM];
int poz = DIM - 1;

using namespace std;
int N,Q;
int val[Nmax];

inline int nr0(int W){
    return ((W^(W-1))&W);
}

void scan(int &VAL)
{
    VAL = 0;
    while('0' > buff[poz] || buff[poz] >'9')
        if(++poz == DIM) fread(buff,1,DIM,stdin),poz=0;
    while('0' <= buff[poz] && buff[poz] <= '9')
    {
        VAL = VAL * 10 + buff[poz] - 48;
        if(++poz == DIM) fread(buff,1,DIM,stdin),poz=0;
    }
}

void read()
{
    scan(N);
    scan(Q);
    for(int i = 1; i <= N; ++i)
        scan(val[i]);
}

class BinaryIndexedTree{
private:
    int range[Nmax];
    int ans;
public:
    int Suma(int lf)
    {
        ans = 0;
        for(int p = lf; p; p-= nr0(p))
            ans += range[p];
        return ans;
    }
    void Build()
    {
        for(int i = 1; i <= N; ++i)
            for(int p = i; p <= N; p += nr0(p))
                range[p] += val[i];
    }
    void Update(int pz,int _newx)
    {
        for(int p = pz; p <= N; p += nr0(p))
            range[p] += _newx;
    }
};
BinaryIndexedTree Aib;

int main()
{
    freopen("aib.in","r",stdin);
    freopen("aib.out","w",stdout);

    read();
    Aib.Build();
    int a,b,op;
    for(int i = 1; i <= Q; ++i)
    {
        scan(op);
        if(op == 0){
            scan(a),scan(b);
            Aib.Update(a,b);
            continue;
        }
        if(op == 1){
            scan(a),scan(b);
            printf("%d\n",Aib.Suma(b) - Aib.Suma(a-1));
        }
        if(op == 2)
        {
            bool gata = 0;
            scan(a);
            int li = 1,lf = N,m,x;
            while(li <= lf)
            {
                m = li + ((lf-li)>>1);
                x = Aib.Suma(m);
                if(x == a){
                    printf("%d\n",m);
                    gata = 1;
                }
                if(x > a)
                    lf = m - 1;
                else
                    li = m + 1;
            }
            if(gata == 0)
                printf("-1\n");
        }
    }

    return 0;
}