Pagini recente » Cod sursa (job #1444379) | Cod sursa (job #2122876) | Cod sursa (job #2569455) | Cod sursa (job #1343031) | Cod sursa (job #2889838)
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;
/*
1-based binary-indexed (fenwick) tree.
positions covered: [1, N]
Aib aib(N); // initialize
aib.inc(1, x); // increment value at position 1 by x
aib.inc(N, x); // increment value at position N by x
aib.prefix_sum(N); // sum over indices [1,N]
aib.range_sum(l,r); // sum over range [l,r]
aib.single(pos); // the value in position pos (1-based indexing)
*/
template<typename T>
struct Aib {
Aib(int n): N{n}, tree{ vector<T>(n+1, 0) } {}
// TODO: initialize from vector
void inc(int pos, T val) {
for(int x = pos; x <= N; x += x&-x) {
tree[x] += val;
}
}
// value at position pos (1-based indexing)
T single(int pos) {
// equivalent to:
// prefix_sum(pos) - prefix_sum(pos-1)
// repeatedly eliminating the smallest bit from (pos) and from (pos-1)
// will meet at: pos - (pos & -pos).
T res = tree[pos];
for(int x = pos-1; x > pos - (pos & -pos); x -= x & x) {
res -= tree[x];
}
return res;
}
// sum over indices [1,pos]
T prefix_sum(int pos) {
T res = 0;
for(int x = pos; x > 0; x -= x & -x) {
res += tree[x];
}
return res;
}
T range_sum(int l, int r) {
return prefix_sum(r) - prefix_sum(l-1);
}
int search(T val) {
int step = 1;
while(step < N) step *= 2;
for(int i = 0; step; step /= 2) {
if (i + step > N) continue;
if (tree[i+step] <= val) {
i += step;
val -= tree[i];
if (val == 0) {
return i;
}
}
}
return -1;
}
private:
int N;
vector<T> tree;
};
ifstream fin {"aib.in"};
ofstream fout {"aib.out"};
int main(void) {
// freopen("v5.aib.in", "r", stdin);
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
int N, M;
fin >> N >> M;
Aib<int> aib(N);
for(int i = 1; i <= N; ++i) {
int x;
fin >> x;
aib.inc(i,x);
}
for(int i = 0; i < M; ++i) {
int q, a, b;
fin >> q;
switch(q) {
case 0:
fin >> a >> b;
aib.inc(a,b);
break;
case 1:
fin >> a >> b;
fout << aib.range_sum(a, b) << "\n";
break;
case 2:
fin >> a;
fout << aib.search(a) << "\n";
}
}
return 0;
}