Cod sursa(job #1696016)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 28 aprilie 2016 11:34:28
Problema Arbori indexati binar Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.5 kb
#include <cstdio>
using namespace std;

int n,m,maxp,aib[200005];

inline int lsb(int arg) {
    return arg&(-arg);
}
inline int sgp(int arg){
    int i;
    for(i=1; i<arg; i<<=1); return i;
}
inline void update(int poz, int val) {
    while(poz<=maxp) {
        aib[poz] += val;
        poz += lsb(poz);
    }
}
inline int query(int poz) {
    int ans=0;
    do {
        ans+= aib[poz];
        poz-= lsb(poz);
    } while(poz);
    return ans;
}
inline int query(int a, int b) {
    return query(b) - query(a-1);
}
inline solve3(int arg) {
    int ans = 0;
    for(int i=maxp; i; i>>=1) {
        if((ans|i)>maxp)
            continue;

        if(query(ans|i)<arg)
            ans|=i;
        else if(query(ans|i)==arg)
            return ans|i;
    }
}

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

    int tmp,tsk,a,b;
    int i;

    scanf("%d%d",&n,&m);
    maxp = sgp(n);

    for(i=1; i<=n; ++i) {
        scanf("%d",&tmp);
        update(i, tmp);
    }
    for(; i<maxp; ++i)
        update(i, 0);

    for(i=1; i<=m; ++i) {
        scanf("%d",&tsk);
        switch(tsk) {
        case 0:
            scanf("%d%d",&a,&b);
            update(a, b);
            break;
        case 1:
            scanf("%d%d",&a,&b);
            printf("%d\n",query(a,b));
            break;
        case 2:
            scanf("%d",&a);
            printf("%d\n",solve3(a));
            break;
        }
    }
    return 0;
}