Pagini recente » Cod sursa (job #143766) | Monitorul de evaluare | Istoria paginii runda/hc_round10 | Cod sursa (job #1118084) | Cod sursa (job #2209997)
#include <iostream>
#include <algorithm>
#include <vector>
namespace algo {
template <typename T>
struct BinaryPlus {
T identity() const { return T(); }
T operator()(const T lhs, const T rhs) const { return lhs + rhs; }
T negate(const T x) const { return -x; }
T times(const T x, const int num_times) const { return x * num_times; }
};
template <typename T, typename Op = BinaryPlus<T>>
class FenwickTree {
public:
FenwickTree(const int n=0) : tree_(n) {}
FenwickTree(const std::vector<T>& v) {
int n = static_cast<int>(v.size());
tree_.assign(n, operation_.identity());
for (int i = 0; i < n; ++i) {
tree_[i] = operation_(tree_[i], v[i]);
if ((i | (i + 1)) < n) {
tree_[i | (i + 1)] = operation_(tree_[i | (i + 1)], tree_[i]);
}
}
}
void Add(int idx, const T value) {
while (idx < static_cast<int>(tree_.size())) {
tree_[idx] = operation_(tree_[idx], value);
idx |= idx + 1;
}
}
T Query(int idx) const {
T answer = operation_.identity();
while (idx >= 0) {
answer = operation_(tree_[idx], answer);
idx = (idx & (idx + 1)) - 1;
}
return answer;
}
T Query(const int left_idx, const int right_idx) const {
return operation_(Query(right_idx), operation_.negate(Query(left_idx - 1)));
}
T PointValue(int idx) const {
T answer = tree_[idx];
if (idx > 0) {
const int to = (idx & (idx + 1)) - 1;
--idx;
while (idx != to) {
answer = operation_(answer, operation_.negate(tree_[idx]));
idx = (idx & (idx + 1)) - 1;
}
}
return answer;
}
void Set(int idx, const T value) {
Add(idx, operation_(operation_.negate(PointValue(idx)), value));
}
int LowerBound(T sum) const {
sum = operation_(sum, operation_.negate(1));
int idx = -1;
for (int step = 1 << (31 - __builtin_clz(tree_.size()));
step; step >>= 1) {
if (idx + step < static_cast<int>(tree_.size())
&& tree_[idx + step] <= sum) {
idx += step;
sum = operation_(sum, operation_.negate(tree_[idx]));
}
}
return idx + 1;
}
private:
std::vector<T> tree_;
Op operation_;
};
} // namespace algo
int main()
{
#ifdef INFOARENA
freopen("aib.in", "r", stdin);
freopen("aib.out", "w", stdout);
#endif
int n, m;
scanf("%d%d", &n, &m);
std::vector<int> v(n);
for (auto& it : v) {
scanf("%d", &it);
}
algo::FenwickTree<int> ft(v);
while (m--> 0) {
int op_type;
scanf("%d", &op_type);
if (op_type == 0) {
int pos, value;
scanf("%d%d", &pos, &value);
--pos;
ft.Add(pos, value);
} else if (op_type == 1) {
int lhs, rhs;
scanf("%d%d", &lhs, &rhs);
--lhs; --rhs;
printf("%d\n", ft.Query(lhs, rhs));
} else {
int sum;
scanf("%d", &sum);
printf("%d\n", ft.LowerBound(sum) + 1);
}
}
return 0;
}