#include "bits/stdc++.h"
using
namespace
std;
constexpr
static
int
MAXSIZE = 1000;
constexpr
static
int
INF = numeric_limits<
int
>::max();
int64_t tree[MAXSIZE];
int64_t lazy[MAXSIZE];
using
QueryAdaptor = tuple<int64_t, int64_t, int64_t>;
void
build_tree(int64_t* arr, int64_t arr_size)
{
stack<QueryAdaptor> st;
st.emplace(1, 0, arr_size - 1);
while
(!st.empty()) {
int64_t currnode, curra, currb;
tie(currnode, curra, currb) = st.top();
st.pop();
if
(curra == INF && currb == INF) {
tree[currnode] = tree[currnode * 2]
+ tree[currnode * 2 + 1];
}
else
if
(curra == currb) {
tree[currnode] = arr[curra];
}
else
{
st.emplace(currnode, INF, INF);
int64_t mid = (curra + currb) / 2;
st.emplace(currnode * 2, curra, mid);
st.emplace(currnode * 2 + 1, mid + 1, currb);
}
}
}
inline
void
push_down(int64_t node, int64_t a, int64_t b)
{
if
(lazy[node] != 0) {
tree[node] += lazy[node] * (b - a + 1);
if
(a != b) {
lazy[2 * node] += lazy[node];
lazy[2 * node + 1] += lazy[node];
}
lazy[node] = 0;
}
}
void
update_tree(int64_t arr_size, int64_t i, int64_t j,
int64_t val)
{
stack<QueryAdaptor> st;
st.emplace(1, 0, arr_size - 1);
while
(!st.empty()) {
int64_t currnode, curra, currb;
tie(currnode, curra, currb) = st.top();
st.pop();
if
(curra == INF && currb == INF) {
tree[currnode] = tree[currnode * 2]
+ tree[currnode * 2 + 1];
}
else
{
push_down(currnode, curra, currb);
if
(curra > currb || curra > j || currb < i) {
continue
;
}
else
if
(curra >= i && currb <= j) {
tree[currnode] += val * (currb - curra + 1);
if
(curra != currb) {
lazy[currnode * 2] += val;
lazy[currnode * 2 + 1] += val;
}
}
else
{
st.emplace(currnode, INF, INF);
int64_t mid = (curra + currb) / 2;
st.emplace(currnode * 2, curra, mid);
st.emplace(currnode * 2 + 1, mid + 1,
currb);
}
}
}
}
int64_t query(int64_t arr_size, int64_t i, int64_t j)
{
stack<QueryAdaptor> st;
st.emplace(1, 0, arr_size - 1);
int64_t result = 0;
while
(!st.empty()) {
int64_t currnode, curra, currb;
tie(currnode, curra, currb) = st.top();
st.pop();
push_down(currnode, curra, currb);
if
(curra > currb || curra > j || currb < i) {
continue
;
}
else
if
(curra >= i && currb <= j) {
result += tree[currnode];
}
else
{
std::int64_t mid = (curra + currb) / 2;
st.emplace(currnode * 2, curra, mid);
st.emplace(currnode * 2 + 1, mid + 1, currb);
}
}
return
result;
}
int
main()
{
memset
(tree, 0,
sizeof
(int64_t) * MAXSIZE);
memset
(lazy, 0,
sizeof
(int64_t) * MAXSIZE);
int64_t arr[] = { 1, 3, 5, 7, 9, 11 };
int
n =
sizeof
(arr) /
sizeof
(arr[0]);
build_tree(arr, n);
cout <<
"Sum of values in given range = "
<< query(n, 1, 3) << endl;
update_tree(n, 1, 5, 10);
cout <<
"Updated sum of values in given range = "
<< query(n, 1, 3) << endl;
return
0;
}