Pagini recente » Cod sursa (job #60367) | Cod sursa (job #698327) | Cod sursa (job #1515356) | Cod sursa (job #30009) | Cod sursa (job #3183550)
#include <bits/stdc++.h>
#define Nat unsigned int
using namespace std;
/**
Arbori indexati binar
Se da un vector a1, a2, ..., an
si se dau Q operatii de doua tipuri:
1 p x : a[p] += x
2 x y : cat este suma a[x]+...+a[y]?
1 2 3 4 5 6 7 8
a = 1 2 3 4 5 6 7 8
Construim un vector aib[] de lungime n
in care
aib[i] = suma elementelor de pe
intervalul a[i-2^k+1]...a[i],
unde k=numarul de biti de 0
de la finalul reprezentarii lui i
in baza 2
indice baza2 interval suma
1 0001 [1,1] 1
2 0010 [1,2] 3
3 0011 [3,3] 3
4 0100 [1,4] 10
5 0101 [5,5] 5
6 0110 [5,6] 11
7 0111 [7,7] 7
8 1000 [1,8] 36
2 2 7 : a[2]+a[3]+...+a[7] =
a[1]+a[2]+...+a[7] - a[1]
[7,7]+[5,6]+[1,4] - [1,1]=
aib[7] + aib[6]+aib[4]-aib[1]
In general interogarea
2 x y o transformam in
suma(a[1]+...+a[y])-suma(a[1]+...a[x-1])
a[p] += x;
a[3] += 10
aib[3] += 10
3+2^0 = 4 : aib[4] += 10
4+2^2 = 8 : aib[8] += 10
*/
ifstream fin("aib.in");
ofstream fout("aib.out");
unsigned int aib[100004], n, Q;
void UpdateOld(Nat p, Nat x)
{
while (p <= n)
{
aib[p] += x;
/// aflu cea mai mare putere a lui
/// 2 divizibila cu p
int k = 1; /// 2^0
while (p % k == 0)
k = k * 2;
k /= 2;
p = p + k;
}
}
void Update(Nat p, Nat x)
{
while (p <= n)
{
aib[p] += x;
p += (p & (-p));
}
}
/// ret. suma a[1]+a[2]+...a[p]
Nat Query(Nat p)
{
Nat suma = 0;
while (p > 0)
{
suma += aib[p];
p -= (p & (-p));
}
return suma;
}
/// cauta cea mai din stanga pozitie p
/// in care sum(a[1..p]) = x
/// daca nu exista pozitia p, afisam -1
void CautBin(Nat x)
{
Nat st, dr, mij, p, val;
st = 1; dr = n;
p = 0;
while (st <= dr)
{
mij = (st + dr) / 2;
val = Query(mij);
if (val == x)
{
p = mij;
dr = mij - 1;
}
else if (val < x) st = mij + 1;
else dr = mij - 1;
}
if (p == 0) fout << "-1\n";
else fout << p << "\n";
}
int main()
{
Nat x, y, op, i;
fin >> n >> Q;
for (i = 1; i <= n; i++)
{
fin >> x;
Update(i, x);
}
for (i = 1; i <= Q; i++)
{
fin >> op;
if (op == 0)
{
fin >> x >> y;
Update(x, y);
}
else if (op == 1)
{
fin >> x >> y;
fout << Query(y) - Query(x-1)<<"\n";
}
else
{
fin >> x;
CautBin(x);
}
}
return 0;
}