Cod sursa(job #2716882)

Utilizator rARES_4Popa Rares rARES_4 Data 5 martie 2021 20:43:21
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.36 kb
#include <iostream>
#include <fstream>
using namespace std;
ifstream f ("aib.in");
ofstream g ("aib.out");
int n,c,x,q;
int s[100001];
/// functia afla cate cifre de 0 are nr in descopunerea binara
int aflare_nr_de_adunat(int nr)
{
    return nr & (-nr);
}
/// functia adauga pe indicii care trebuie numarul
/// de exemplu daca adugam elementul de pe pozitia 1 il vom adauga la pozitia 1,2,4,8
///numarul nu are niciun 0 la final in descomp binara asa ca punem numarul pe poz+2^nr de zerouri => pozitia 2
/// apoi 2 are 1 zero in descomp binara asa ca poz + 2^2 este 4
///si la final il mai punem pe pozitia 8 deoarece 4 are 2 cifre de 0 in descomp binara
void add(int nr,int indice)
{
    if(indice>n)
        return;
    s[indice] += nr;
    int nr_de_adunat = aflare_nr_de_adunat(indice);
    add(nr,indice+ nr_de_adunat);
}
/// functia afla suma de la 1 la poz face pasii inversi de la functia add
/// mergem de la cel mai mare si scadem din poz - 2 ^ nr de cifre de 0 in descomp binara
int suma(int poz)
{
    int sum = 0;
    while(poz>=1)
    {
        sum +=s[poz];
        poz-=aflare_nr_de_adunat(poz);
    }
    return sum;
}
/// facem o cautare binara pentru cazul in care c == 2
int cb(int sum)
{
    int st = 1,dr = n,mij,rasp = -1;
    while(st<=dr)
    {
        mij = (st+dr)/2;
        int suma_calc = suma(mij);
        if(suma_calc == sum)
        {
            rasp = mij;
            dr = mij - 1;
        }
        else if(suma_calc>sum)
        {
           dr = mij - 1;
        }
        else
        {
            st = mij +1;
        }
    }
    return rasp;
}
int main()
{
    f >> n>>q;
    for(int i = 1; i<=n; i++)
    {
        f >> x;
        add(x,i);
    }
    for(int i = 1; i<=q; i++)
    {
        f >> c;
        if(c == 0)
        {
            int a,b;
            f >> a >> b;
            add(b,a);
        }
        else if(c == 1)
        {
            int a,b;
            f >> a >> b;
            /// pentru a afla suma pe un interval facem ca la sume partiale
            /// facem suma 1 ... b din care scadem suma de 1 .... a-1
            int suma_b = suma(b);
            int suma_a = suma(a-1);
            g << suma_b - suma_a<< '\n';
        }
        else if(c == 2)
        {
            int x;
            f >> x;
            g << cb(x)<< '\n';

        }
    }
}