Cod sursa(job #2331595)

Utilizator vladboss2323Ciorica Vlad vladboss2323 Data 29 ianuarie 2019 18:43:27
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.68 kb
#include <iostream>
#include <fstream>
using namespace std;

ifstream in("aib.in");
ofstream out("aib.out");

/*
x & (-x) = cea mai mica putere a lui 2 din desc lui x
EX
x = 000110100 = 52
x - 1 = 000110011
-x = 111001100
     000110100
*/

int aib[100005],n,m,S[100005];
int suma(int p)
{
    //calc v[1] + v[2] + ... + v[p]
    int sum = 0, p2;
    while (p != 0)
    {
        sum += aib[p];
        p2 = p & (-p);
        p -= p2;
    }
    return sum;
}

void actual(int p, int val)
{
    int p2;
    while (p <= n)
    {
        aib[p] += val;
        p2 = p & (-p);
        p += p2;
    }
}

/*
pas = 1 << L;//cea mai mare putere a lui 2 mai mica sau egala cu n
while(pas != 0)
{
    if (r+pas <= n && aib[r + pas] <= s)
    {
        r += pas;
        s -= aib[r];
    }
    pas /= 2;
}
*/


int main()
{
    int i,p,tip,x,y,st,dr,mid,ok,pas;
    in>>n>>m;
    for(i=1; i<=n; i++)
    {
        in>>x;
        S[i]=S[i-1]+x;
    }
    for(i=1; i<=n; i++)
    {
        p=i & (-i);
        aib[i]=S[i]-S[i-p];
    }
    /*for(i=1; i<=n; i++)
        out<<aib[i]<<" ";
    out<<endl;
    */
    for(i=1; i<=m; i++)
    {
        in>>tip;
        if(tip==0)
        {
            in>>x>>y;
            actual(x,y);
        }
        else if(tip==1)
        {
            in>>x>>y;
            out<<suma(y)-suma(x-1)<<'\n';
        }
        else if(tip==2)
        {
            in>>x;
            /*st=1;
            dr=n;
            ok=0;
            while(st!=dr && ok==0)
            {
                mid=(st+dr)/2;
                y=suma(mid);
                //out<<y<<" "<<mid<<" ";
                if(y==x)
                {
                    ok=1;
                }
                if(y<x)
                {
                    st=mid+1;
                }
                else
                {
                    dr=mid;
                }
            }
            //out<<st<<" ";
            if(suma(st)==x)
                out<<st<<endl;
            else if(suma(dr)==x)
                out<<dr<<endl;
            else
                out<<-1<<endl;
            */
            int r=0;
            pas = 1 << 16;//cea mai mare putere a lui 2 mai mica sau egala cu n
            while(pas != 0)
            {
                if (r+pas <= n && aib[r + pas] <= x)
                {
                    r += pas;
                    x -= aib[r];
                }
                pas /= 2;
            }
            if(x!=0)
                out<<-1<<'\n';
            else if(r==0)
                out<<-1<<'\n';
            else
                out<<r<<'\n';
        }
    }
    return 0;
}