#include <iostream>
#include <fstream>
const int NMAX = 1e5;
int n;
int seg_tree[4 * NMAX];
int a[1 + NMAX];
void build(int index, int left, int right) {
if (left == right) {
seg_tree[index] = a[left];
return;
}
int left_child = index * 2;
int right_child = index * 2 + 1;
int mid = (left + right) / 2;
build(left_child, left, mid);
build(right_child, mid + 1, right);
seg_tree[index] = seg_tree[left_child] + seg_tree[right_child];
}
void print_seg_tree(int index, int left, int right) {
std::printf("index : %d, interval (%d, %d), value : %d\n", index, left, right, seg_tree[index]);
if (left == right) {
return;
}
int left_child = index * 2;
int right_child = index * 2 + 1;
int mid = (left + right) / 2;
print_seg_tree(left_child, left, mid);
print_seg_tree(right_child, mid + 1, right);
}
void point_update(int index, int left, int right, int target_index, int update_value) {
if (left == right) {
if (left != target_index)
exit(-147);
seg_tree[index] += update_value;
return;
}
int left_child = 2 * index;
int right_child = 2 * index + 1;
int mid = (left + right) / 2;
if (mid >= target_index)
point_update(left_child, left, mid, target_index, update_value);
else
point_update(right_child, mid + 1, right, target_index, update_value);
seg_tree[index] = seg_tree[left_child] + seg_tree[right_child];
}
int range_query(int index, int left, int right, int query_left, int query_right) {
if (left == right) {
if (query_left <= left && left <= query_right)
return seg_tree[index];
else
return 0;
}
if (query_left > right || left > query_right)
return 0;
if (query_left <= left && right <= query_right)
return seg_tree[index];
int left_child = 2 * index;
int right_child = 2 * index + 1;
int mid = (left + right) / 2;
return range_query(left_child, left, mid, query_left, query_right) + range_query(right_child, mid + 1, right, query_left, query_right);
}
int binary_search(int value) {
// std::printf("searching value %d\n", value);
int left = 1;
int right = n;
int seg_tree_index = 1;
while (left <= right) {
// std::printf("at left = %d, right = %d, in seg tree : %d, remaining = %d \n", left, right, seg_tree[seg_tree_index], value);
if (left == right) {
if (value != seg_tree[seg_tree_index])
return -1;
return left;
}
int left_child = seg_tree_index * 2;
int right_child = seg_tree_index * 2 + 1;
int mid = (left + right) / 2;
if (value > seg_tree[left_child]) {
seg_tree_index = right_child;
left = mid + 1;
value -= seg_tree[left_child];
}
else {
seg_tree_index = left_child;
right = mid;
}
}
}
int main() {
std::ifstream in("aib.in");
std::ofstream out("aib.out");
int m;
in >> n >> m;
for (int i = 1; i <= n; ++i)
in >> a[i];
build(1, 1, n);
for (int i = 1; i <= m; ++i) {
int type;
in >> type;
switch (type) {
case 0:
int index, value;
in >> index >> value;
// std::printf("updating %d with + %d\n", index, value);
point_update(1, 1, n, index, value);
// std::cout << "DEBUG..\n";
// print_seg_tree(1, 1, n);
// std::cout << "END..\n";
break;
case 1:
int left, right;
in >> left >> right;
out << range_query(1, 1, n, left, right) << '\n';
break;
case 2:
int sum;
in >> sum;
out << binary_search(sum) << '\n';
break;
default:
exit(-209);
}
}
return 0;
}