Cod sursa(job #1688058)

Utilizator mariakKapros Maria mariak Data 13 aprilie 2016 11:17:21
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.78 kb
#include <bits/stdc++.h>
#define Nmax 100002
#define Log 17
FILE *fin  = freopen("aib.in", "r", stdin);
FILE *fout = freopen("aib.out", "w", stdout);

using namespace std;
int n, m, aib[Nmax];
void update(int val, int pos)
{
    do
    {
        aib[pos] += val;
        /// suppose pos = a1b where 1 is the last 1 bit from left to right
        /// -pos = pos- + 1 = (a-)0(b-) + 1= (a-)0(0...0)- + 1 =
        /// = (a-)0(1...1) + 1 = (a-)1(0...0) => -pos = (a-)1b
        /// pos & (-pos) = a1b & (a-)1b = (0...0)1(0...0) => pos & (-pos) =
        /// 1 << k ,where k is the last 1 bit from left to right

        pos += (pos & (- pos));
    }
    while(pos <= n);
}
int sum(int pos)
{
    int s = 0;
    while(pos)
    {
        s += aib[pos];
        pos -= (pos & (- pos));
    }
    return s;
}
void read()
{
    int i, x;
    scanf("%d %d", &n, &m);
    for(i = 1; i <= n; ++ i)
    {
        scanf("%d", &x);
        update(x, i);
    }
}
int bsearch(int x)
{
    int i = 0, p = 1 << Log;
    while(p)
    {
        if(i + p <= n && aib[i + p] < x)
        {
            i += p;
            x -= aib[i];
        }
        p >>= 1;
    }
    return i;
}
void solution()
{
    int t, a, b, k;
    while(m --)
    {
        scanf("%d", &t);
        if(t == 0)
        {
            scanf("%d %d", &a, &b);
            update(b, a);
        }
        if(t == 1)
        {
            scanf("%d %d", &a, &b);
            printf("%d\n", sum(b) - sum(a - 1));
        }
        if(t == 2)
        {
            scanf("%d", &a);
            k = bsearch(a);
            if(sum(k + 1) == a)
                printf("%d\n", k + 1);
            else printf("-1\n");
        }
    }
}
int main()
{
    read();
    solution();
    return 0;
}