Count and Toggle Queries on a Binary Array | JavaScript 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
let MAX = 100000 ; let tree = new Array ( MAX ) ; let lazy = new Array ( MAX ) ; for ( let i = 0 ; i < MAX ; i ++ ) { tree [ i ] = 0 ; lazy [ i ] = false ; } function toggle ( node , st , en , us , 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 ; } let mid = Math . floor ( ( 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 ] ; } } function countQuery ( node , st , en , qs , 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 ] ; } let mid = Math . floor ( ( st + en ) / 2 ) ; return countQuery ( ( node << 1 ) , st , mid , qs , qe ) + countQuery ( ( node << 1 ) + 1 , mid + 1 , en , qs , qe ) ; } let n = 5 ; toggle ( 1 , 0 , n - 1 , 1 , 2 ) ; toggle ( 1 , 0 , n - 1 , 2 , 4 ) ; document . write ( countQuery ( 1 , 0 , n - 1 , 2 , 3 ) + " " ) ; toggle ( 1 , 0 , n - 1 , 2 , 4 ) ; document . write ( countQuery ( 1 , 0 , n - 1 , 1 , 4 ) + " " ) ;