Cod sursa(job #1654694)

Utilizator malina_floreaMalina Florea malina_florea Data 17 martie 2016 13:03:36
Problema Arbori indexati binar Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.55 kb
#include <fstream>
#define DMAX 200010
using namespace std;
FILE * fin = fopen("aib.in", "r");
FILE * fout = fopen("aib.out", "w");

void citire();
int cauta(int, int);
void update(int, int);
int query(int);
inline int last(int);

int aib[DMAX];
int n, m;

int main()
{
    int i, c, a, b;
    
    citire();
    
    for (i=1; i<=m; i++)
    {
        fscanf(fin, "%d", &c);
        if (c==0)
        {
            fscanf(fin, "%d %d", &a, &b);
            update(a, b);
        }
        else
            if (c==1)
            {
                fscanf(fin, "%d %d", &a, &b);
                fprintf(fout, "%d\n", query(b)-query(a-1));
            }
            else
            {
                fscanf(fin, "%d", &a);
                fprintf(fout, "%d\n", cauta(1, a));
            }
    }
    
    fclose(fin);
    fclose(fout);
    return 0;
}

void citire()
{
    int i, x;
    
    fscanf(fin, "%d %d", &n, &m);
    for (i=1; i<=n; i++)
    {
        fscanf(fin, "%d", &x);
        update(i, x);
    }
}

void update(int poz, int val)
{
    if (poz>n) return;
    aib[poz]+=val;
    update(poz+last(poz), val);
}

inline int last(int x)
{
    return (x&(~(x-1)));
}

int query(int poz)
{
    if (poz==0) return 0;
    return aib[poz]+query(poz-last(poz));
}

int cauta(int poz, int sum)
{
    //returneaza ultima pozitie la care se formeaza suma sua
    if (sum==0) return poz-1;
    
    int aux=0;
    while (poz<=n && sum>=aib[poz])
    {
        aux=poz;
        poz+=last(poz);
    }
    
    if (aux==0) return -1;
    
    return cauta(aux+1, sum-aib[aux]);
}