Cod sursa(job #943092)

Utilizator supermitelArdelean Razvan Mitel supermitel Data 24 aprilie 2013 11:35:02
Problema Arbori indexati binar Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.64 kb
#include <cstdio>
#include <algorithm>
#include <deque>

using namespace std;

struct tree
{
    tree *st, *dr;
    int val;
    tree(int v = 0)
    {
        st = NULL;
        dr = NULL;
        val = v;
    }
};

tree *root;
int n,m;

void constr(deque< tree *> init)
{
    deque< tree *> final;
    tree * aux, *first, *sec;

    if(init.front() == init.back())
    {
        root = init.front();
        return;
    }

    while(!init.empty())
    {
        first = init.front();
        init.pop_front();
        if(init.empty())
            aux = first;
        else
        {
            sec = init.front();
            init.pop_front();
            aux = new tree;
            aux -> val = first-> val + sec-> val;
            aux -> st = first;
            aux -> dr = sec;
        }
        final.push_back(aux);
    }

    constr(final);
}

void citire()
{
    deque< tree *> sir;
    int i, cit;
    tree *aux;
    scanf("%d%d\n",&n, &m);
    for(i=0; i<n; i++)
    {
        scanf("%d",&cit);
        aux = new tree;
        *aux = cit;
        sir.push_back(aux);
    }
    constr(sir);
}

void debug( tree * t)
{
    if(t == NULL)
        return;
    printf("(%d",t->val);
    debug(t->st);
    printf("");
    debug(t->dr);
    printf(")");
}

void add(int val, int poz, tree *t, int x, int y)
{
    if(poz<x || poz>y || t==NULL)
        return;
    t->val += val;
    if(x==y)
        return;
    add(val, poz, t->st, x, x+(y-x)/2);
    add(val, poz, t->dr, x+(y-x)/2+1, y);
}

int sum(int a, int b, tree *t, int x, int y)
{
    if(t == NULL)
        return 0;
    if(a<=x && b>=y)
        return t->val;
    if(y<a || x>b)
        return 0;
    return sum(a, b, t->st, x, x+(y-x)/2)
            + sum(a, b,t->dr, x+(y-x)/2+1, y);
}

int doi(int a, tree *t, int x, int y)
{
    if(t->val<=a)
        return y;
    if(t->st == NULL)
        return x-1;
    if(t->st->val < a)
        return doi(a - t->st->val, t->st, x+(y-x)/2+1, y);
    return doi(a, t->st, x, x+(y-x)/2);
}

int main()
{
    freopen("aib.in","r",stdin);
    freopen("aib.out","w",stdout);
    citire();
    int command, a, b;
    for(int i=0; i < m; i++)
    {
        scanf("%d",&command);
        switch(command)
        {
        case 0:
            scanf("%d%d",&a,&b);
            add(b,a-1,root,0,n-1);
            break;
        case 1:
            scanf("%d%d",&a,&b);
            printf("%d\n",sum(a-1, b-1, root, 0, n-1));
            break;
        case 2:
            scanf("%d",&a);
            printf("%d\n",doi(a, root, 0, n-1)+1);
        }
    }
    return 0;
}