Pagini recente » Profil mamaie | Cod sursa (job #180695) | Cod sursa (job #5040) | Cod sursa (job #20564) | Cod sursa (job #295098)
Cod sursa(job #295098)
#include <cstdio>
// NOTE: we use an imaginary array 'el', to reference actual values.
// Thus, for example, tree[12] = tree[10] + tree[11] + el[12];
// and tree[10] = tree[9] + el[10]; ( because tree[2k + 1] = el[2k + 1] )
template<class treeT>
class BinaryIndexedTree {
treeT *tree;
int N;
treeT fixed_sum(int pos); // return el[1]+...+el[pos]
public:
BinaryIndexedTree(int n)
{
tree = new treeT [n];
N = n;
};
void add(int pos, treeT S); // adds a number S to el[pos]
treeT sum(int pos1, int pos2); // sum of el in interval [a,b]
int q2(treeT X); // return k such that el[1]+...+el[k] = X
};
template<class treeT>
treeT BinaryIndexedTree<treeT>::fixed_sum(int pos)
{
treeT sum = 0;
while(pos) {
sum += tree[pos];
pos = (pos - 1) & pos;
}
return sum;
}
template<class treeT>
void BinaryIndexedTree<treeT>::add(int pos, treeT S)
{
while (pos <= N) {
tree[pos] += S;
pos += -pos & pos;
}
}
template<class treeT>
treeT BinaryIndexedTree<treeT>::sum(int pos1, int pos2)
{
return fixed_sum(pos2) - fixed_sum(pos1 - 1);
}
template<class treeT>
int BinaryIndexedTree<treeT>::q2(treeT X)
{
int step, i;
// we do a horny (sorry, I like calling interesting code snippets "sexy") BS:
for (step = 1; step <= N; step <<= 1);
for (i = 0; step; step >>= 1) {
if (i + step <= N)
if (fixed_sum(i + step) <= X) i += step;
}
if (fixed_sum(i) != X) return -1;
else return i;
}
int main()
{
int N, M, i, v1, v2, t;
unsigned long elem;
freopen("aib.in", "r", stdin);
freopen("aib.out", "w", stdout);
scanf("%d %d\n", &N, &M);
BinaryIndexedTree<unsigned long> aib(N);
for (i = 1; i <= N; ++i) {
scanf("%lu ", &elem);
aib.add(i, elem);
}
for (i = 0; i != M; ++i) {
scanf("%d ", &t);
if (t == 2) {
scanf("%lu\n", &elem);
printf("%d\n", aib.q2(elem));
} else {
scanf("%d %d\n", &v1, &v2);
if (!t) aib.add(v1, v2);
else printf("%lu\n", aib.sum(v1, v2));
}
}
return 0;
}