// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
#define MAX 15
int tree[MAX] = { 0 };
int lazy[MAX] = { 0 };
// Function to build the segment tree
void build(int arr[],int node, int a, int b)
{
if (a == b) {
tree[node] = arr[a];
return;
}
// left child
build(arr,2 * node, a, (a + b) / 2);
// right child
build(arr,2 * node + 1, 1 + (a + b) / 2, b);
tree[node] = tree[node * 2] +
tree[node * 2 + 1];
}
void update_tree(int node, int a,
int b, int i, int j)
{
// If lazy of node is 1 then
// value in current node
// needs to be flipped
if (lazy[node] != 0) {
// Update it
tree[node] = tree[node] * (-1);
if (a != b) {
// flip value in lazy
lazy[node * 2] =
!(lazy[node * 2]);
// flip value in lazy
lazy[node * 2 + 1] =
!(lazy[node * 2 + 1]);
}
// Reset the node lazy value
lazy[node] = 0;
}
// Current segment is not
// within range [i, j]
if (a > b || a > j || b < i)
return;
// Segment is fully
// within range
if (a >= i && b <= j) {
tree[node] = tree[node] * (-1);
// Not leaf node
if (a != b) {
// Flip the value as if lazy is
// 1 and again asked to flip
// value then without flipping
// value two times
lazy[node * 2] =
!(lazy[node * 2]);
lazy[node * 2 + 1] =
!(lazy[node * 2 + 1]);
}
return;
}
// Updating left child
update_tree(node * 2, a,
(a + b) / 2, i, j);
// Updating right child
update_tree(1 + node * 2, 1 +
(a + b) / 2, b, i, j);
// Updating root with
// sum of its child
tree[node] = tree[node * 2] +
tree[node * 2 + 1];
}
int query_tree(int node, int a,
int b, int i, int j)
{
// Out of range
if (a > b || a > j || b < i)
return 0;
// If lazy of node is 1 then value
// in current node needs to be flipped
if (lazy[node] != 0) {
tree[node] = tree[node] * (-1);
if (a != b) {
lazy[node * 2] =
!(lazy[node * 2]);
// flip value in lazy
lazy[node * 2 + 1] =
!(lazy[node * 2 + 1]);
}
lazy[node] = 0;
}
// Current segment is totally
// within range [i, j]
if (a >= i && b <= j)
return tree[node];
// Query left child
int q1 = query_tree(node * 2, a,
(a + b) / 2, i, j);
// Query right child
int q2 = query_tree(1 + node * 2,
1 + (a + b) / 2, b, i, j);
// Return final result
return q1 + q2;
}
int main()
{
int arr[]={1,2,3,4,5};
int n=sizeof(arr)/sizeof(arr[0]);
// Building segment tree
build(arr,1, 0, n - 1);
// Array is { 1, 2, 3, 4, 5 }
cout << query_tree(1, 0, n - 1, 0, 4) << endl;
// Flip range 0 to 4
update_tree(1, 0, n - 1, 0, 4);
// Array becomes { -1, -2, -3, -4, -5 }
cout << query_tree(1, 0, n - 1, 0, 4) << endl;
// Flip range 0 to 2
update_tree(1, 0, n - 1, 0, 2);
// Array becomes { 1, 2, 3, -4, -5 }
cout << query_tree(1, 0, n - 1, 0, 4) << endl;
}