Count and Toggle Queries on a Binary Array | C ++ program to implement toggle and count queries on a binary array . ; segment tree to store count of 1 's within range ; bool type tree to collect the updates for toggling the values of 1 and 0 in given range ; function for collecting updates of toggling node -- > index of current node in segment tree st -- > starting index of current node en -- > ending index of current node us -- > starting index of range update query ue -- > ending index of range update query ; If lazy value is non - zero for current node of segment tree , then there are some pending updates . So we need to make sure that the pending updates are done before making new updates . Because this value may be used by parent after recursive calls ( See last line of this function ) ; Make pending updates using value stored in lazy nodes ; checking if it is not leaf node because if it is leaf node then we cannot go further ; We can postpone updating children we don ' t ▁ ▁ need ▁ their ▁ new ▁ values ▁ now . ▁ ▁ Since ▁ we ▁ are ▁ not ▁ yet ▁ updating ▁ children ▁ of ▁ ' node ',  we need to set lazy flags for the children ; out of range ; Current segment is fully in range ; Add the difference to current node ; same logic for checking leaf node or not ; This is where we store values in lazy nodes , rather than updating the segment tree itelf Since we don 't need these updated values now  we postpone updates by storing values in lazy[] ; If not completely in rang , but overlaps , recur for children , ; And use the result of children calls to update this node ; function to count number of 1 's within given range ; current node is out of range ; If lazy flag is set for current node of segment tree , then there are some pending updates . So we need to make sure that the pending updates are done before processing the sub sum query ; Make pending updates to this node . Note that this node represents sum of elements in arr [ st . . en ] and all these elements must be increased by lazy [ node ] ; checking if it is not leaf node because if it is leaf node then we cannot go further ; Since we are not yet updating children os si , we need to set lazy values for the children ; At this point we are sure that pending lazy updates are done for current node . So we can return value If this segment lies in range ; If a part of this segment overlaps with the given range ; Driver program to run the case ; Toggle 1 2 ; Toggle 2 4 ; Count 2 3 ; Toggle 2 4 ; Count 1 4
#include <bits/stdc++.h> NEW_LINE using namespace std ; const int MAX = 100000 ; int tree [ MAX ] = { 0 } ; bool lazy [ MAX ] = { false } ; void toggle ( int node , int st , int en , int us , int ue ) { if ( lazy [ node ] ) { lazy [ node ] = false ; tree [ node ] = en - st + 1 - tree [ node ] ; if ( st < en ) { lazy [ node << 1 ] = ! lazy [ node << 1 ] ; lazy [ 1 + ( node << 1 ) ] = ! lazy [ 1 + ( node << 1 ) ] ; } } if ( st > en us > en ue < st ) return ; if ( us <= st && en <= ue ) { tree [ node ] = en - st + 1 - tree [ node ] ; if ( st < en ) { lazy [ node << 1 ] = ! lazy [ node << 1 ] ; lazy [ 1 + ( node << 1 ) ] = ! lazy [ 1 + ( node << 1 ) ] ; } return ; } int mid = ( st + en ) / 2 ; toggle ( ( node << 1 ) , st , mid , us , ue ) ; toggle ( ( node << 1 ) + 1 , mid + 1 , en , us , ue ) ; if ( st < en ) tree [ node ] = tree [ node << 1 ] + tree [ ( node << 1 ) + 1 ] ; } int countQuery ( int node , int st , int en , int qs , int qe ) { if ( st > en qs > en qe < st ) return 0 ; if ( lazy [ node ] ) { lazy [ node ] = false ; tree [ node ] = en - st + 1 - tree [ node ] ; if ( st < en ) { lazy [ node << 1 ] = ! lazy [ node << 1 ] ; lazy [ ( node << 1 ) + 1 ] = ! lazy [ ( node << 1 ) + 1 ] ; } } if ( qs <= st && en <= qe ) return tree [ node ] ; int mid = ( st + en ) / 2 ; return countQuery ( ( node << 1 ) , st , mid , qs , qe ) + countQuery ( ( node << 1 ) + 1 , mid + 1 , en , qs , qe ) ; } int main ( ) { int n = 5 ; toggle ( 1 , 0 , n - 1 , 1 , 2 ) ; toggle ( 1 , 0 , n - 1 , 2 , 4 ) ; cout << countQuery ( 1 , 0 , n - 1 , 2 , 3 ) << endl ; toggle ( 1 , 0 , n - 1 , 2 , 4 ) ; cout << countQuery ( 1 , 0 , n - 1 , 1 , 4 ) << endl ; return 0 ; }