Pagini recente » Cod sursa (job #2408444) | Cod sursa (job #1600927) | Cod sursa (job #2927849) | Cod sursa (job #2882838) | Cod sursa (job #2984877)
#include <bits/stdc++.h>
using namespace std;
const int NMAX = 1e5 + 1;
int v[NMAX], aib[NMAX];
int n, m;
/**
Def : Adica primul bit 1 din scrierea in baza 2 a lui x.
Ex. least_significant_bit(6) = ?
6 -> in baza 2 = 00000110
^
x & (-x) = 00000010
=> least_significant_bit(6) = 00000010
**/
int least_significant_bit(int x) {
return x & (-x);
}
/**
Def. update(nod, val) = cresc cu val toate intervalele afectate
de cresterea lui v[nod] cu val
Acest update este folosit si la construirea aib-ului!
**/
void update(int nod, int val) {
while(nod <= n) {
/// se cresc cu val intervalele care il contin pe nod
aib[nod] += val;
/// trecem la urmatorul interval care il contine pe nod
nod += least_significant_bit(nod);
}
}
/**
Def. query(nod) = suma din intervalul [1, nod]
Explicatie :
- daca incepem de la aib[nod], deja ajungem la un
interval [x, nod], care este chiar intervalul terminal
- de aici, de fiecare data cand la parintele nodului ajungem,
la un alt interval [y, x-1], s.a.m.d. pana cand ajungem la [1, z].
- insumate, ele dau chiar intervalul [1, nod]
**/
int query(int nod) {
int sum = 0;
while(nod) {
/// ne aflam pe un interval din interiorul lui [1, nod]
sum += aib[nod];
/// trecem la parintele lui nod
nod -= least_significant_bit(nod);
}
return sum;
}
/// efectiv facem cautare binara clasica
int cb(int sum) {
int st = 1, dr = n, ind = -1;
while(st <= dr) {
int mij = (st + dr) / 2;
int s = query(mij); // suma din intervalul [0, s]
if(s == sum)
ind = mij;
if(s < sum)
st = mij + 1;
else
dr = mij - 1;
}
return ind;
}
int main() {
ifstream cin("aib.in");
ofstream cout("aib.out");
cin >> n >> m;
for(int i = 1; i <= n; i++) {
int x;
cin >> x;
update(i, x);
}
for(int i = 1; i <= m; i++) {
int c;
cin >> c;
if(c == 0) { // la v[poz] se adauga val
int poz, val;
cin >> poz >> val;
update(poz, val);
}
else if(c == 1) { // suma din intervalul [a, b];
int a, b;
cin >> a >> b;
cout << query(b) - query(a - 1) << '\n';
}
else { // x = ? a.i. query(x) == sum
int sum;
cin >> sum;
cout << cb(sum) << '\n';
}
}
return 0;
}