import
java.util.Arrays;
import
java.util.List;
import
java.util.Stack;
class
GFG
{
static
final
int
MAXSIZE =
1000
;
static
final
int
INF = (
int
) Double.POSITIVE_INFINITY;
static
int
[] tree =
new
int
[MAXSIZE];
static
int
[] lazy =
new
int
[MAXSIZE];
static
void
build_tree(
int
[] arr,
int
arr_size)
{
Stack<List<Integer>> st =
new
Stack<>();
st.push(Arrays.asList(
1
,
0
, arr_size -
1
));
while
(!st.isEmpty())
{
int
currnode, curra, currb;
List<Integer> temp = st.peek();
currnode = temp.get(
0
);
curra = temp.get(
1
);
currb = temp.get(
2
);
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.push(Arrays.asList(currnode, INF, INF));
int
mid = (curra + currb) /
2
;
st.push(Arrays.asList(currnode *
2
, curra, mid));
st.push(Arrays.asList(currnode *
2
+
1
, mid +
1
, currb));
}
}
}
static
void
push_down(
int
node,
int
a,
int
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
;
}
}
static
void
update_tree(
int
arr_size,
int
i,
int
j,
int
val)
{
Stack<List<Integer>> st =
new
Stack<>();
st.push(Arrays.asList(
1
,
0
, arr_size -
1
));
while
(!st.isEmpty())
{
int
currnode, curra, currb;
List<Integer> temp = st.peek();
currnode = temp.get(
0
);
curra = temp.get(
1
);
currb = temp.get(
2
);
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.push(Arrays.asList(currnode, INF, INF));
int
mid = (curra + currb) /
2
;
st.push(Arrays.asList(currnode *
2
, curra, mid));
st.push(Arrays.asList(currnode *
2
+
1
,
mid +
1
, currb));
}
}
}
}
static
int
query(
int
arr_size,
int
i,
int
j)
{
Stack<List<Integer>> st =
new
Stack<>();
st.push(Arrays.asList(
1
,
0
, arr_size -
1
));
int
result =
0
;
while
(!st.isEmpty())
{
int
currnode, curra, currb;
List<Integer> temp = st.peek();
currnode = temp.get(
0
);
curra = temp.get(
1
);
currb = temp.get(
2
);
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
{
int
mid = (curra + currb) /
2
;
st.push(Arrays.asList(currnode *
2
, curra, mid));
st.push(Arrays.asList(currnode *
2
+
1
, mid +
1
, currb));
}
}
return
result;
}
public
static
void
main(String[] args)
{
Arrays.fill(tree,
0
);
Arrays.fill(lazy,
0
);
int
arr[] = {
1
,
3
,
5
,
7
,
9
,
11
};
int
n = arr.length;
build_tree(arr, n);
System.out.printf(
"Sum of values in given range = %d\n"
, query(n,
1
,
3
));
update_tree(n,
1
,
5
,
10
);
System.out.printf(
"Updated sum of values in given range = %d\n"
, query(n,
1
,
3
));
}
}