Pagini recente » Cod sursa (job #3235845) | Cod sursa (job #2707415) | Cod sursa (job #2798591) | Cod sursa (job #2697356) | Cod sursa (job #2716882)
#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';
}
}
}