#include <bits/stdc++.h>
using namespace std;
ifstream fin("datorii.in");
ofstream fout("datorii.out");
const int UPDATE_QUERY_TYPE = 0;
const int SUM_QUERY_TYPE = 1;
class OnlineIntervalSumTree {
public:
virtual void subtract(int position, int value) = 0;
virtual int getSum(int leftIndex, int rightIndex) const = 0;
};
class SegmentTree : public OnlineIntervalSumTree {
private:
static constexpr int ROOT_NODE_INDEX = 1;
vector<int> nodeValue;
int arrayLength;
public:
SegmentTree(const vector<short>& numbers) {
arrayLength = numbers.size();
nodeValue = vector<int>(getSegmentTreeSize(arrayLength));
for (int i = 0; i < arrayLength; i++) {
add(i, numbers[i], ROOT_NODE_INDEX, 0, arrayLength - 1);
}
}
void subtract(int position, int value) override {
add(position - 1, -value, ROOT_NODE_INDEX, 0, arrayLength - 1);
}
int getSum(int leftIndex, int rightIndex) const override {
return getSum(leftIndex - 1, rightIndex - 1, ROOT_NODE_INDEX, 0, arrayLength - 1);
}
private:
void add(int position, int value, int node, int nodeSegmentLeftIndex, int nodeSegmentRightIndex) {
// we are in the node whose index is "node", and nodeValue[node]=array[nodeLeft]+...+array[nodeRight]
if (nodeSegmentLeftIndex == nodeSegmentRightIndex) {
nodeValue[node] += value;
return;
}
int middleIndex = (nodeSegmentLeftIndex + nodeSegmentRightIndex) / 2;
int leftChildNode = 2 * node;
int rightChildNode = leftChildNode + 1;
// left child: 2*node, nodeValue[2*node]=sum from nodeSegmentLeftIndex, middleIndex
// right child:2*node+1, ...
if (position <= middleIndex) {
add(position, value, leftChildNode, nodeSegmentLeftIndex, middleIndex);
} else {
add(position, value, rightChildNode, middleIndex + 1, nodeSegmentRightIndex);
}
nodeValue[node] += value;
}
int getSum(int leftIndex, int rightIndex, int node, int nodeSegmentLeftIndex, int nodeSegmentRightIndex) const {
if (isRangeWithinRange(nodeSegmentLeftIndex, nodeSegmentRightIndex, leftIndex, rightIndex)) {
return nodeValue[node];
}
int middleIndex = (nodeSegmentLeftIndex + nodeSegmentRightIndex) / 2;
int leftChildNode = 2 * node;
int rightChildNode = leftChildNode + 1;
int subtreeSum = 0;
if (leftIndex <= middleIndex) {
subtreeSum += getSum(leftIndex, rightIndex, leftChildNode, nodeSegmentLeftIndex, middleIndex);
}
if (rightIndex > middleIndex) {
subtreeSum += getSum(leftIndex, rightIndex, rightChildNode, middleIndex + 1, nodeSegmentRightIndex);
}
return subtreeSum;
}
private:
static int constexpr getSegmentTreeSize(int arrayLength) {
return 4 * arrayLength;
}
static int constexpr isRangeWithinRange(int firstRangeLeft, int firstRangeRight, int secondRangeLeft, int secondRangeRight) {
return firstRangeLeft >= secondRangeLeft && firstRangeRight <= secondRangeRight;
}
};
class FenwickTree : public OnlineIntervalSumTree {
private:
vector<int> internalArray;
public:
FenwickTree(const vector<short>& numbers) : internalArray{ vector<int>((int)numbers.size() + 1) } {
for (int i = 0; i < numbers.size(); i++) {
subtract(i + 1, -numbers[i]);
}
}
void subtract(int position, int value) override {
for (int i = position; i < (int)internalArray.size(); i += getMostSignificantPowerOfTwo(i)) {
internalArray[i] -= value;
}
}
int getSum(int leftIndex, int rightIndex) const override {
// int rightSum = getPrefixSum(rightIndex);
// int leftSum = getPrefixSum(leftIndex - 1);
// cout << "left=" << leftSum <<". right=" << rightSum << "\n";
return getPrefixSum(rightIndex) - getPrefixSum(leftIndex - 1);
}
private:
// internalArray[k] = realArray[k-f(k)+1] + ... + realArray[k]
static int constexpr getMostSignificantPowerOfTwo(int position) {
return position & (-position);
}
int getPrefixSum(int index) const {
if (index == 0) {
return 0;
}
int sum = 0;
for (int i = index; i > 0; i -= getMostSignificantPowerOfTwo(i)) {
sum += internalArray[i];
}
return sum;
}
};
vector<short> readNumbers(int arrayLength) {
vector<short> numbers(arrayLength);
for (int i = 0; i < arrayLength; i++) {
fin >> numbers[i];
}
return numbers;
}
void processUpdate(OnlineIntervalSumTree& segmentTree) {
int position;
int value;
fin >> position >> value;
segmentTree.subtract(position, value);
}
int processGetSum(const OnlineIntervalSumTree& segmentTree) {
int leftIndex;
int rightIndex;
fin >> leftIndex >> rightIndex;
return segmentTree.getSum(leftIndex, rightIndex);
}
void processQueries(int countQueries, OnlineIntervalSumTree& segmentTree) {
for (int i = 0; i < countQueries; i++) {
int queryType;
fin >> queryType;
if (queryType == UPDATE_QUERY_TYPE) {
processUpdate(segmentTree);
} else {
fout << processGetSum(segmentTree) << "\n";
}
}
}
int main() {
int arrayLength;
int countQueries;
fin >> arrayLength >> countQueries;
vector<short> numbers = readNumbers(arrayLength); // do we need move here? or is it automatically moved?
FenwickTree segmentTree{ numbers };
processQueries(countQueries, segmentTree);
return 0;
}