Cod sursa(job #2142258)

Utilizator DavidLDavid Lauran DavidL Data 24 februarie 2018 21:25:50
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.88 kb
#include <fstream>
#define MAX 100005
using namespace std;
ifstream fi("aib.in");
ofstream fo("aib.out");

int n,m;
int A[MAX];

inline int lst(int x)
{
    return (x^(x-1))&x;
}

void build()
{
    for (int i=1; i<=n; i++)
    {
        /// determinam A[i]
        int x=i-1;
        while (x>i-lst(i))
        {
            A[i]+=A[x];
            x-=lst(x);
        }
    }
}

void update(int poz,int val)
{
    int x=poz;

    while (x<=n)
    {
        A[x]+=val;
        x+=lst(x);
    }
}

int sum(int poz)
{
    /// suma din 1...poz
    int x=poz,rez=0;
    while (x>0)
    {
        rez+=A[x];
        x-=lst(x);
    }
    return rez;
}

int pozitie(int val)
{
    /// pe ce pozitie avem suma de la 1 la k = val
    int x=0,l,sum;
    while ((1<<(x+1))<=n && A[1<<x]<=val)
        x++;
    if (A[1<<x]>val && x>=0)
        x--;
    if (x<0)
        return -1;

    l=1<<x; /// lungimea curenta
    x=1<<x; /// pozitia pe care ne aflam
    sum=A[x];
    while (sum<val && x<=n && l)
    {
        l>>=1;
        while (x+l>n)
            l>>=1;

        while (l>=1 && A[x+l]+sum>val)
            l>>=1;

        if (!l)
            break;
        sum+=A[x+l];
        x+=l;
    }
    if (sum==val)
        return x;
    return -1;
}

int main()
{
    fi>>n>>m;
    for (int i=1; i<=n; i++)
    {
        fi>>A[i];
    }
    build();

    //for (int i=1; i<=n; i++)
        //fo<<"suma de la "<<i-lst[i]+1<<" la "<<i<<": "<<A[i]<<"\n";

    while (m--)
    {
        int op,a,b;
        fi>>op;
        if (op==0)
        {
            fi>>a>>b;
            update(a,b);
        }
        else if (op==1)
        {
            fi>>a>>b;
            fo<<sum(b)-sum(a-1)<<"\n";
        }
        else
        {
            fi>>a;
            fo<<pozitie(a)<<"\n";
        }
    }

    return 0;
}