Number of primes in a subarray ( with updates ) | Javascript program to find number of prime numbers in a subarray and performing updates ; If prime [ p ] is not changed , then it is a prime ; Update all multiples of p ; A utility function to get the middle index from corner indexes . ; A recursive function to get the number of primes in a given range of array indexes . The following are parameters for this function . st -- > Poleter to segment tree index -- > Index of current node in the segment tree . Initially 0 is passed as root is always at index 0 ss & se -- > Starting and ending indexes of the segment represented by current node , i . e . , st [ index ] qs & qe -- > Starting and ending indexes of query range ; If segment of this node is a part of given range , then return the number of primes in the segment ; If segment of this node is outside the given range ; If a part of this segment overlaps with the given range ; A recursive function to update the nodes which have the given index in their range . The following are parameters st , si , ss and se are same as getSumUtil ( ) i -- > index of the element to be updated . This index is in input array . diff -- > Value to be added to all nodes which have i in range ; Base Case : If the input index lies outside the range of this segment ; If the input index is in range of this node , then update the value of the node and its children ; The function to update a value in input array and segment tree . It uses updateValueUtil ( ) to update the value in segment tree ; Check for erroneous input index ; Update the value in array ; Case 1 : Old and new values both are primes ; Case 2 : Old and new values both non primes ; Case 3 : Old value was prime , new value is non prime ; Case 4 : Old value was non prime , new_val is prime ; Update the values of nodes in segment tree ; Return number of primes in range from index qs ( query start ) to qe ( query end ) . It mainly uses queryPrimesUtil ( ) ; A recursive function that constructs Segment Tree for array [ ss . . se ] . si is index of current node in segment tree st ; If there is one element in array , check if it is prime then store 1 in the segment tree else store 0 and return ; if arr [ ss ] is prime ; If there are more than one elements , then recur for left and right subtrees and store the sum of the two values in this node ; Function to construct segment tree from given array . This function allocates memory for segment tree and calls constructSTUtil ( ) to fill the allocated memory ; Height of segment tree ; Maximum size of segment tree ; Fill the allocated memory st ; Return the constructed segment tree ; Driver code ; Preprocess all primes till MAX . Create a boolean array " isPrime [ 0 . . MAX ] " . A value in prime [ i ] will finally be false if i is Not a prime , else true . ; Build segment tree from given array ; Query 1 : Query ( start = 0 , end = 4 ) ; Query 2 : Update ( i = 3 , x = 6 ) , i . e Update a [ i ] to x ; Query 3 : Query ( start = 0 , end = 4 )
let MAX = 1000 ; function sieveOfEratosthenes ( isPrime ) { isPrime [ 1 ] = false ; for ( let p = 2 ; p * p <= MAX ; p ++ ) { if ( isPrime [ p ] == true ) { for ( let i = p * 2 ; i <= MAX ; i += p ) isPrime [ i ] = false ; } } } function getMid ( s , e ) { return Math . floor ( s + ( e - s ) / 2 ) ; } function queryPrimesUtil ( st , ss , se , qs , qe , index ) { if ( qs <= ss && qe >= se ) return st [ index ] ; if ( se < qs ss > qe ) return 0 ; let mid = getMid ( ss , se ) ; return queryPrimesUtil ( st , ss , mid , qs , qe , 2 * index + 1 ) + queryPrimesUtil ( st , mid + 1 , se , qs , qe , 2 * index + 2 ) ; } function updateValueUtil ( st , ss , se , i , diff , si ) { if ( i < ss i > se ) return ; st [ si ] = st [ si ] + diff ; if ( se != ss ) { let mid = getMid ( ss , se ) ; updateValueUtil ( st , ss , mid , i , diff , 2 * si + 1 ) ; updateValueUtil ( st , mid + 1 , se , i , diff , 2 * si + 2 ) ; } } function updateValue ( arr , st , n , i , new_val , isPrime ) { if ( i < 0 i > n - 1 ) { document . write ( " " ) ; return ; } let diff = 0 ; let oldValue ; oldValue = arr [ i ] ; arr [ i ] = new_val ; if ( isPrime [ oldValue ] && isPrime [ new_val ] ) return ; if ( ( ! isPrime [ oldValue ] ) && ( ! isPrime [ new_val ] ) ) return ; if ( isPrime [ oldValue ] && ! isPrime [ new_val ] ) { diff = - 1 ; } if ( ! isPrime [ oldValue ] && isPrime [ new_val ] ) { diff = 1 ; } updateValueUtil ( st , 0 , n - 1 , i , diff , 0 ) ; } function queryPrimes ( st , n , qs , qe ) { let primesInRange = queryPrimesUtil ( st , 0 , n - 1 , qs , qe , 0 ) ; document . write ( " " + qs + " " + qe + " " + primesInRange + " " ) ; } function constructSTUtil ( arr , ss , se , st , si , isPrime ) { if ( ss == se ) { if ( isPrime [ arr [ ss ] ] ) st [ si ] = 1 ; else st [ si ] = 0 ; return st [ si ] ; } let mid = getMid ( ss , se ) ; st [ si ] = constructSTUtil ( arr , ss , mid , st , si * 2 + 1 , isPrime ) + constructSTUtil ( arr , mid + 1 , se , st , si * 2 + 2 , isPrime ) ; return st [ si ] ; } function constructST ( arr , n , isPrime ) { let x = ( Math . ceil ( Math . log ( n ) / Math . log ( 2 ) ) ) ; let max_size = 2 * Math . pow ( 2 , x ) - 1 ; let st = new Array ( max_size ) ; constructSTUtil ( arr , 0 , n - 1 , st , 0 , isPrime ) ; return st ; } let arr = [ 1 , 2 , 3 , 5 , 7 , 9 ] ; let n = arr . length ; let isPrime = new Array ( MAX + 1 ) ; isPrime . fill ( true ) ; sieveOfEratosthenes ( isPrime ) ; let st = constructST ( arr , n , isPrime ) ; let start = 0 ; let end = 4 ; queryPrimes ( st , n , start , end ) ; let i = 3 ; let x = 6 ; updateValue ( arr , st , n , i , x , isPrime ) ; start = 0 ; end = 4 ; queryPrimes ( st , n , start , end ) ;