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 Code ; Toggle 1 2 ; Toggle 2 4 ; Count 2 3 ; Toggle 2 4 ; Count 1 4
using System ; public class GFG { static readonly int MAX = 100000 ; static int [ ] tree = new int [ MAX ] ; static bool [ ] lazy = new bool [ MAX ] ; static 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 ] ; } } static 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 ) ; } public static void Main ( ) { int n = 5 ; toggle ( 1 , 0 , n - 1 , 1 , 2 ) ; toggle ( 1 , 0 , n - 1 , 2 , 4 ) ; Console . WriteLine ( countQuery ( 1 , 0 , n - 1 , 2 , 3 ) ) ; toggle ( 1 , 0 , n - 1 , 2 , 4 ) ; Console . WriteLine ( countQuery ( 1 , 0 , n - 1 , 1 , 4 ) ) ; } }