Sum of prime numbers in range [L, R] from given Array for Q queries
Given an array arr[] of the size of N followed by an array of Q queries, of the following two types:
- Query Type 1: Given two integers L and R, find the sum of prime elements from index L to R where 0 <= L <= R <= N-1.
- Query Type 2: Given two integers i and X, change arr[i] = X where 0 <= i <= n-1.
Note: Every first index of the subquery determines the type of query to be answered.
Example:Â
Input: arr[] = {1, 3, 5, 7, 9, 11}, Q = { { 1, 1, 3}, {2, 1, 10}, {1, 1, 3 } }
Output:Â
15
12
Explanation:Â
First query is of type 1, so answer is (3 + 5 + 7), = 15
Second query is of type 2, so arr[1] = 10
Third query is of type 1, where arr[1] = 10, which is not prime hence answer is (5 + 7) = 12Input: arr[] = {1, 2, 35, 7, 14, 11}, Q = { {2, 4, 3}, {1, 4, 5 } }
Output: 14
Explanation:
First query is of type 2, So update arr[4] = 3
Second query is of type 1, since arr[4] = 3, which is prime. So answer is (3 + 11) = 14
Naive Approach: The idea is to iterate for each query between L to R and perform the required operation on the given array.Â
Time Complexity: O(Q Â * N * (O(sqrt(max(arr[i]))
Approach:Â To optimize the problem use Segment tree and Sieve Of Eratosthenes.
- First, create a boolean array that will mark the prime numbers.
- Now while making the segment tree only add those array elements as leaf nodes which are prime.
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; Â
int const MAX = 1000001; bool prime[MAX]; Â
// Function to find the prime numbers void SieveOfEratosthenes() {     // Create a boolean array prime[]     // and initialize all entries it as true     // A value in prime[i] will     // finally be false if i is Not a prime     memset (prime, true , sizeof (prime)); Â
    for ( int p = 2; p * p <= MAX; p++) { Â
        // Check if prime[p] is not         // changed, then it is a prime         if (prime[p] == true ) { Â
            // Update all multiples of p             // greater than or equal to             // the square of it numbers             // which are multiple of p             // and are less than p^2 are             // already been marked             for ( int i = p * p; i <= MAX; i += p)                 prime[i] = false ;         }     } } Â
// Function to get the middle // index from corner indexes int getMid( int s, int e) { Â Â Â Â return s + (e - s) / 2; } Â
// Function to get the sum of // values in the given range // of the array Â
int getSumUtil( int * st, int ss,                int se, int qs,                int qe, int si) {     // If segment of this node is a     // part of given range, then     // return the sum of the segment     if (qs <= ss && qe >= se)         return st[si]; Â
    // If segment of this node is     // outside the given range     if (se < qs || ss > qe)         return 0; Â
    // If a part of this segment     // overlaps with the given range     int mid = getMid(ss, se); Â
    return getSumUtil(st, ss, mid,                       qs, qe,                       2 * si + 1)            + getSumUtil(st, mid + 1,                         se, qs, qe,                         2 * si + 2); } Â
// Function to update the nodes which // have the given index in their range void updateValueUtil( int * st, int ss,                      int se, int i,                      int diff, int si) {     // If the input index lies     // outside the range of     // this segment     if (i < ss || i > se)         return ; Â
    // If the input index is in     // range of this node, then update     // the value of the node and its children     st[si] = st[si] + diff;     if (se != ss) {         int mid = getMid(ss, se);         updateValueUtil(st, ss, mid, i,                         diff, 2 * si + 1);         updateValueUtil(st, mid + 1,                         se, i, diff,                         2 * si + 2);     } } Â
// Function to update a value in // input array and segment tree void updateValue( int arr[], int * st,                  int n, int i,                  int new_val) {     // Check for erroneous input index     if (i < 0 || i > n - 1) {         cout << "-1" ;         return ;     } Â
    // Get the difference between     // new value and old value     int diff = new_val - arr[i]; Â
    int prev_val = arr[i]; Â
    // Update the value in array     arr[i] = new_val; Â
    // Update the values of     // nodes in segment tree     // only if either previous     // value or new value     // or both are prime     if (prime[new_val]         || prime[prev_val]) { Â
        // If only new value is prime         if (!prime[prev_val])             updateValueUtil(st, 0, n - 1,                             i, new_val, 0); Â
        // If only new value is prime         else if (!prime[new_val])             updateValueUtil(st, 0, n - 1,                             i, -prev_val, 0); Â
        // If both are prime         else             updateValueUtil(st, 0, n - 1,                             i, diff, 0);     } } Â
// Return sum of elements in range // from index qs (query start) to qe // (query end). It mainly uses getSumUtil() int getSum( int * st, int n, int qs, int qe) {     // Check for erroneous input values     if (qs < 0 || qe > n - 1 || qs > qe) {         cout << "-1" ;         return -1;     } Â
    return getSumUtil(st, 0, n - 1,                       qs, qe, 0); } Â
// Function that constructs Segment Tree int constructSTUtil( int arr[], int ss,                     int se, int * st,                     int si) {     // If there is one element in     // array, store it in current node of     // segment tree and return     if (ss == se) { Â
        // Only add those elements in segment         // tree which are prime         if (prime[arr[ss]])             st[si] = arr[ss];         else             st[si] = 0;         return st[si];     } Â
    // If there are more than one     // elements, then recur for left and     // right subtrees and store the     // sum of values in this node     int mid = getMid(ss, se);     st[si]         = constructSTUtil(arr, ss, mid,                           st, si * 2 + 1)           + constructSTUtil(arr, mid + 1,                             se, st,                             si * 2 + 2);     return st[si]; } Â
// Function to construct segment // tree from given array int * constructST( int arr[], int n) { Â Â Â Â // Allocate memory for the segment tree Â
    // Height of segment tree     int x = ( int )( ceil (log2(n))); Â
    // Maximum size of segment tree     int max_size = 2 * ( int ) pow (2, x) - 1; Â
    // Allocate memory     int * st = new int [max_size]; Â
    // Fill the allocated memory st     constructSTUtil(arr, 0, n - 1, st, 0); Â
    // Return the constructed segment tree     return st; } Â
// Driver code int main() { Â Â Â Â int arr[] = { 1, 3, 5, 7, 9, 11 }; Â Â Â Â int n = sizeof (arr) / sizeof (arr[0]); Â
    int Q[3][3]         = { { 1, 1, 3 },             { 2, 1, 10 },             { 1, 1, 3 } }; Â
    // Function call     SieveOfEratosthenes(); Â
    // Build segment tree from given array     int * st = constructST(arr, n); Â
    // Print sum of values in     // array from index 1 to 3     cout << getSum(st, n, 1, 3) << endl; Â
    // Update: set arr[1] = 10     // and update corresponding     // segment tree nodes     updateValue(arr, st, n, 1, 10); Â
    // Find sum after the value is updated     cout << getSum(st, n, 1, 3) << endl;     return 0; } |
Java
// Java program for the above approach import java.io.*; import java.util.*; class GFG { Â
  static int MAX = 1000001 ;   static int prime[] = new int [MAX]; Â
  // Function to find the prime numbers   static void SieveOfEratosthenes()   { Â
    // Create a boolean array prime[]     // and initialize all entries it as true     // A value in prime[i] will     // finally be false if i is Not a prime     Arrays.fill(prime, 1 ); Â
    for ( int p = 2 ; p * p <= MAX; p++)     { Â
      // Check if prime[p] is not       // changed, then it is a prime       if (prime[p] == 1 )       { Â
        // Update all multiples of p         // greater than or equal to         // the square of it numbers         // which are multiple of p         // and are less than p^2 are         // already been marked         for ( int i = p * p; i <= MAX - 1 ; i += p)           prime[i] = 0 ;       }     }   } Â
  // Function to get the middle   // index from corner indexes   static int getMid( int s, int e)   {     return s + (e - s) / 2 ;   } Â
  // Function to get the sum of   // values in the given range   // of the array   static int getSumUtil( int [] st, int ss,                         int se, int qs,                         int qe, int si)   { Â
    // If segment of this node is a     // part of given range, then     // return the sum of the segment     if (qs <= ss && qe >= se)       return st[si]; Â
    // If segment of this node is     // outside the given range     if (se < qs || ss > qe)       return 0 ; Â
    // If a part of this segment     // overlaps with the given range     int mid = getMid(ss, se); Â
    return getSumUtil(st, ss, mid,                       qs, qe,                       2 * si + 1 )       + getSumUtil(st, mid + 1 ,                    se, qs, qe,                    2 * si + 2 );   } Â
  // Function to update the nodes which   // have the given index in their range   static void updateValueUtil( int [] st, int ss,                               int se, int i,                               int diff, int si)   { Â
    // If the input index lies     // outside the range of     // this segment     if (i < ss || i > se)       return ; Â
    // If the input index is in     // range of this node, then update     // the value of the node and its children     st[si] = st[si] + diff;     if (se != ss)     {       int mid = getMid(ss, se);       updateValueUtil(st, ss, mid, i,                       diff, 2 * si + 1 );       updateValueUtil(st, mid + 1 ,                       se, i, diff,                       2 * si + 2 );     }   } Â
  // Function to update a value in   // input array and segment tree   static void updateValue( int arr[], int [] st,                           int n, int i, int new_val)   { Â
    // Check for erroneous input index     if (i < 0 || i > n - 1 )     {       System.out.print( "-1" );       return ;     } Â
    // Get the difference between     // new value and old value     int diff = new_val - arr[i]; Â
    int prev_val = arr[i]; Â
    // Update the value in array     arr[i] = new_val; Â
    // Update the values of     // nodes in segment tree     // only if either previous     // value or new value     // or both are prime     if ((prime[new_val] | prime[prev_val]) != 0 )     { Â
      // If only new value is prime       if (prime[prev_val] == 0 )         updateValueUtil(st, 0 , n - 1 ,                         i, new_val, 0 ); Â
      // If only new value is prime       else if (prime[new_val] == 0 )         updateValueUtil(st, 0 , n - 1 , i, -prev_val, 0 ); Â
      // If both are prime       else         updateValueUtil(st, 0 , n - 1 ,                         i, diff, 0 );     }   } Â
  // Return sum of elements in range   // from index qs (query start) to qe   // (query end). It mainly uses getSumUtil()   static int getSum( int [] st, int n, int qs, int qe)   { Â
    // Check for erroneous input values     if (qs < 0 || qe > n - 1 || qs > qe)     {       System.out.println( "-1" );       return - 1 ;     } Â
    return getSumUtil(st, 0 , n - 1 ,                       qs, qe, 0 );   } Â
  // Function that constructs Segment Tree   static int constructSTUtil( int arr[], int ss,                              int se, int [] st, int si)   {     // If there is one element in     // array, store it in current node of     // segment tree and return     if (ss == se) { Â
      // Only add those elements in segment       // tree which are prime       if (prime[arr[ss]] != 0 )         st[si] = arr[ss];       else         st[si] = 0 ;       return st[si];     } Â
    // If there are more than one     // elements, then recur for left and     // right subtrees and store the     // sum of values in this node     int mid = getMid(ss, se);     st[si] = constructSTUtil(arr, ss, mid,                              st, si * 2 + 1 )       + constructSTUtil(arr, mid + 1 ,                         se, st,                         si * 2 + 2 );     return st[si];   } Â
  // Function to construct segment   // tree from given array   static int [] constructST( int arr[], int n)   {     // Allocate memory for the segment tree Â
    // Height of segment tree     int x = ( int )(Math.ceil(Math.log(n)/Math.log( 2 ))); Â
    // Maximum size of segment tree     int max_size = 2 * ( int )Math.pow( 2 , x) - 1 ; Â
    // Allocate memory     int [] st = new int [max_size]; Â
    // Fill the allocated memory st     constructSTUtil(arr, 0 , n - 1 , st, 0 ); Â
    // Return the constructed segment tree     return st;   } Â
  // Driver Code   public static void main(String[] args)   {     int arr[] = { 1 , 3 , 5 , 7 , 9 , 11 };     int n = arr.length; Â
    int Q[][] = { { 1 , 1 , 3 },                  { 2 , 1 , 10 },                  { 1 , 1 , 3 } }; Â
    // Function call     SieveOfEratosthenes(); Â
    // Build segment tree from given array     int [] st = constructST(arr, n); Â
    // Print sum of values in     // array from index 1 to 3     System.out.println(getSum(st, n, 1 , 3 )); Â
    // Update: set arr[1] = 10     // and update corresponding     // segment tree nodes     updateValue(arr, st, n, 1 , 10 ); Â
    // Find sum after the value is updated     System.out.println(getSum(st, n, 1 , 3 ));   } } Â
// This code is contributed by susmitakundugoaldanga |
Python3
# Python3 program for the above approach import math MAX = 1000001 Â
# Create a boolean array prime[] # and initialize all entries it as true # A value in prime[i] will # finally be false if i is Not a prime prime = [ True ] * MAX Â
# Function to find prime numbers def SieveOfEratosthenes():          p = 2     while p * p < = MAX :                  # Check if prime[p] is not         # changed, then it is a prime         if prime[p] = = True :                          # Update all multiples of p             # greater than or equal to             # the square of it numbers             # which are multiple of p             # and are less than p^2 are             # already been marked             for i in range (p * p, MAX , p):                 prime[i] = False                  p + = 1          # Function to get the middle # index from corner indexes def getMid(s, e):          return s + (e - s) / / 2 Â
# Function to get the sum of # values in the given range # of the array def getSumUtil(st, ss, se, qs, qe, si):          # If segment of this node is a     # part of given range, then     # return the sum of the segment     if qs < = ss and qe > = se:         return st[si]          # If segment of this node is     # outside the given range     if se < qs or ss > qe:         return 0          # If a part of this segment     # overlaps with the given range     mid = getMid(ss, se)          return (getSumUtil(st, ss, mid, qs,                        qe, 2 * si + 1 ) +             getSumUtil(st, mid + 1 , se,                        qs, qe, 2 * si + 2 )) Â
# Function to update the nodes which # have the given index in their range def updateValueUtil(st, ss, se, i, diff, si):          # If the input index lies     # outside the range of     # this segment     if i < ss or i > se:         return          # If the input index is in     # range of this node, then update     # the value of the node and its children     st[si] = st[si] + diff          if se ! = ss:         mid = getMid(ss, se)         updateValueUtil(st, ss, mid, i,                         diff, 2 * si + 1 )         updateValueUtil(st, mid + 1 , se, i,                         diff, 2 * si + 2 )          # Function to update a value in # input array and segment tree def updateValue(arr, st, n, i, new_val):          # Check for erroneous input index     if i < 0 or i > n - 1 :         print ( - 1 )         return          # Get the difference between     # new value and old value     diff = new_val - arr[i]          prev_val = arr[i]          # Update the value in array     arr[i] = new_val          # Update the values of nodes     # in segment tree only if     # either previous value or     # new value or both are prime     if prime[new_val] or prime[prev_val]:                  # If only new value is prime         if not prime[prev_val]:             updateValueUtil(st, 0 , n - 1 ,                             i, new_val, 0 )                  # If only old value is prime         elif not prime[new_val]:             updateValueUtil(st, 0 , n - 1 , i,                             - prev_val, 0 )                  # If both are prime         else :             updateValueUtil(st, 0 , n - 1 ,                             i, diff, 0 )              # Return sum of elements in range # from index qs (query start) to qe # (query end). It mainly uses getSumUtil() def getSum(st, n, qs, qe):          # Check for erroneous input values     if qs < 0 or qe > n - 1 or qs > qe:         return - 1          return getSumUtil(st, 0 , n - 1 , qs, qe, 0 ) Â
# Function that constructs the Segment Tree def constructSTUtil(arr, ss, se, st, si):          # If there is one element in     # array, store it in current     # node of segment tree and return     if ss = = se:                  # Only add those elements in segment         # tree which are prime         if prime[arr[ss]]:             st[si] = arr[ss]         else :             st[si] = 0                  return st[si]          # If there are more than one     # elements, then recur for left and     # right subtrees and store the     # sum of values in this node     mid = getMid(ss, se)     st[si] = (constructSTUtil(arr, ss, mid, st,                               2 * si + 1 ) +               constructSTUtil(arr, mid + 1 , se,                               st, 2 * si + 2 ))     return st[si] Â
# Function to construct segment # tree from given array def constructST(arr, n):          # Allocate memory for the segment tree          # Height of segment tree     x = int (math.ceil(math.log2(n)))          # Maximum size of segment tree     max_size = 2 * int ( pow ( 2 , x)) - 1          # Allocate memory     st = [ 0 ] * max_size          # Fill the allocated memory st     constructSTUtil(arr, 0 , n - 1 , st, 0 )          # Return the constructed segment tree     return st Â
# Driver code arr = [ 1 , 3 , 5 , 7 , 9 , 11 ] n = len (arr) Â
Q = [ [ 1 , 1 , 3 ], Â Â Â Â Â Â [ 2 , 1 , 10 ], Â Â Â Â Â Â [ 1 , 1 , 3 ] ] Â
# Function call SieveOfEratosthenes() Â
# Build segment tree from given array st = constructST(arr, n) Â
# Print sum of values in # array from index 1 to 3 print (getSum(st, n, 1 , 3 )) Â
# Update: set arr[1] = 10 # and update corresponding # segment tree nodes updateValue(arr, st, n, 1 , 10 ) Â
# Find sum after value is updated print (getSum(st, n, 1 , 3 )) Â
# This code is contributed by Stuti Pathak |
C#
// C# program for the above approach using System; class GFG {        static int MAX = 1000001;   static int [] prime = new int [MAX];     // Function to find the prime numbers   static void SieveOfEratosthenes()   {       // Create a boolean array prime[]     // and initialize all entries it as true     // A value in prime[i] will     // finally be false if i is Not a prime     Array.Fill(prime, 1);       for ( int p = 2; p * p <= MAX; p++)     {         // Check if prime[p] is not       // changed, then it is a prime       if (prime[p] == 1)       {           // Update all multiples of p         // greater than or equal to         // the square of it numbers         // which are multiple of p         // and are less than p^2 are         // already been marked         for ( int i = p * p; i <= MAX - 1; i += p)           prime[i] = 0;       }     }   }     // Function to get the middle   // index from corner indexes   static int getMid( int s, int e)   {     return s + (e - s) / 2;   }     // Function to get the sum of   // values in the given range   // of the array   static int getSumUtil( int [] st, int ss,                         int se, int qs,                         int qe, int si)   {       // If segment of this node is a     // part of given range, then     // return the sum of the segment     if (qs <= ss && qe >= se)       return st[si];       // If segment of this node is     // outside the given range     if (se < qs || ss > qe)       return 0;       // If a part of this segment     // overlaps with the given range     int mid = getMid(ss, se);       return getSumUtil(st, ss, mid,                       qs, qe,                       2 * si + 1)       + getSumUtil(st, mid + 1,                    se, qs, qe,                    2 * si + 2);   }     // Function to update the nodes which   // have the given index in their range   static void updateValueUtil( int [] st, int ss,                               int se, int i,                               int diff, int si)   {       // If the input index lies     // outside the range of     // this segment     if (i < ss || i > se)       return ;       // If the input index is in     // range of this node, then update     // the value of the node and its children     st[si] = st[si] + diff;     if (se != ss)     {       int mid = getMid(ss, se);       updateValueUtil(st, ss, mid, i,                       diff, 2 * si + 1);       updateValueUtil(st, mid + 1,                       se, i, diff,                       2 * si + 2);     }   }     // Function to update a value in   // input array and segment tree   static void updateValue( int [] arr, int [] st,                           int n, int i, int new_val)   {       // Check for erroneous input index     if (i < 0 || i > n - 1)     {       Console.Write( "-1" );       return ;     }       // Get the difference between     // new value and old value     int diff = new_val - arr[i];       int prev_val = arr[i];       // Update the value in array     arr[i] = new_val;       // Update the values of     // nodes in segment tree     // only if either previous     // value or new value     // or both are prime     if ((prime[new_val] | prime[prev_val]) != 0)     {         // If only new value is prime       if (prime[prev_val] == 0)         updateValueUtil(st, 0, n - 1,                         i, new_val, 0);         // If only new value is prime       else if (prime[new_val] == 0)         updateValueUtil(st, 0, n - 1, i, -prev_val, 0);         // If both are prime       else         updateValueUtil(st, 0, n - 1,                         i, diff, 0);     }   }     // Return sum of elements in range   // from index qs (query start) to qe   // (query end). It mainly uses getSumUtil()   static int getSum( int [] st, int n, int qs, int qe)   {       // Check for erroneous input values     if (qs < 0 || qe > n - 1 || qs > qe)     {       Console.WriteLine( "-1" );       return -1;     }       return getSumUtil(st, 0, n - 1,                       qs, qe, 0);   }     // Function that constructs Segment Tree   static int constructSTUtil( int [] arr, int ss,                              int se, int [] st, int si)   {          // If there is one element in     // array, store it in current node of     // segment tree and return     if (ss == se) {         // Only add those elements in segment       // tree which are prime       if (prime[arr[ss]] != 0)         st[si] = arr[ss];       else         st[si] = 0;       return st[si];     }       // If there are more than one     // elements, then recur for left and     // right subtrees and store the     // sum of values in this node     int mid = getMid(ss, se);     st[si] = constructSTUtil(arr, ss, mid,                              st, si * 2 + 1)       + constructSTUtil(arr, mid + 1,                         se, st,                         si * 2 + 2);     return st[si];   }     // Function to construct segment   // tree from given array   static int [] constructST( int [] arr, int n)   {          // Allocate memory for the segment tree       // Height of segment tree     int x = ( int )(Math.Ceiling(Math.Log(n,2)));       // Maximum size of segment tree     int max_size = 2 * ( int )Math.Pow(2, x) - 1;       // Allocate memory     int [] st = new int [max_size];       // Fill the allocated memory st     constructSTUtil(arr, 0, n - 1, st, 0);       // Return the constructed segment tree     return st;   }      // Driver code   static void Main()   {     int [] arr = { 1, 3, 5, 7, 9, 11 };     int n = arr.Length;       // Function call     SieveOfEratosthenes();       // Build segment tree from given array     int [] st = constructST(arr, n);       // Print sum of values in     // array from index 1 to 3     Console.WriteLine(getSum(st, n, 1, 3));       // Update: set arr[1] = 10     // and update corresponding     // segment tree nodes     updateValue(arr, st, n, 1, 10);       // Find sum after the value is updated     Console.WriteLine(getSum(st, n, 1, 3));   } } Â
// This code is contributed by divyesh072019. |
Javascript
<script>     // Javascript program for the above approach          let MAX = 1000001;     let prime = new Array(MAX); Â
    // Function to find the prime numbers     function SieveOfEratosthenes()     { Â
      // Create a boolean array prime[]       // and initialize all entries it as true       // A value in prime[i] will       // finally be false if i is Not a prime       prime.fill(1); Â
      for (let p = 2; p * p <= MAX; p++)       { Â
        // Check if prime[p] is not         // changed, then it is a prime         if (prime[p] == 1)         { Â
          // Update all multiples of p           // greater than or equal to           // the square of it numbers           // which are multiple of p           // and are less than p^2 are           // already been marked           for (let i = p * p; i <= MAX - 1; i += p)             prime[i] = 0;         }       }     } Â
    // Function to get the middle     // index from corner indexes     function getMid(s, e)     {       return s + parseInt((e - s) / 2, 10);     } Â
    // Function to get the sum of     // values in the given range     // of the array     function getSumUtil(st, ss, se, qs, qe, si)     { Â
      // If segment of this node is a       // part of given range, then       // return the sum of the segment       if (qs <= ss && qe >= se)         return st[si]; Â
      // If segment of this node is       // outside the given range       if (se < qs || ss > qe)         return 0; Â
      // If a part of this segment       // overlaps with the given range       let mid = getMid(ss, se); Â
      return getSumUtil(st, ss, mid,                         qs, qe,                         2 * si + 1)         + getSumUtil(st, mid + 1,                      se, qs, qe,                      2 * si + 2);     } Â
    // Function to update the nodes which     // have the given index in their range     function updateValueUtil(st, ss, se, i, diff, si)     { Â
      // If the input index lies       // outside the range of       // this segment       if (i < ss || i > se)         return ; Â
      // If the input index is in       // range of this node, then update       // the value of the node and its children       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 to update a value in     // input array and segment tree     function updateValue(arr, st, n, i, new_val)     { Â
      // Check for erroneous input index       if (i < 0 || i > n - 1)       {         document.write( "-1" );         return ;       } Â
      // Get the difference between       // new value and old value       let diff = new_val - arr[i]; Â
      let prev_val = arr[i]; Â
      // Update the value in array       arr[i] = new_val; Â
      // Update the values of       // nodes in segment tree       // only if either previous       // value or new value       // or both are prime       if ((prime[new_val] | prime[prev_val]) != 0)       { Â
        // If only new value is prime         if (prime[prev_val] == 0)           updateValueUtil(st, 0, n - 1,                           i, new_val, 0); Â
        // If only new value is prime         else if (prime[new_val] == 0)           updateValueUtil(st, 0, n - 1, i, -prev_val, 0); Â
        // If both are prime         else           updateValueUtil(st, 0, n - 1,                           i, diff, 0);       }     } Â
    // Return sum of elements in range     // from index qs (query start) to qe     // (query end). It mainly uses getSumUtil()     function getSum(st, n, qs, qe)     { Â
      // Check for erroneous input values       if (qs < 0 || qe > n - 1 || qs > qe)       {         document.write( "-1" );         return -1;       } Â
      return getSumUtil(st, 0, n - 1,                         qs, qe, 0);     } Â
    // Function that constructs Segment Tree     function constructSTUtil(arr, ss, se, st, si)     {       // If there is one element in       // array, store it in current node of       // segment tree and return       if (ss == se) { Â
        // Only add those elements in segment         // tree which are prime         if (prime[arr[ss]] != 0)           st[si] = arr[ss];         else           st[si] = 0;         return st[si];       } Â
      // If there are more than one       // elements, then recur for left and       // right subtrees and store the       // sum of values in this node       let mid = getMid(ss, se);       st[si] = constructSTUtil(arr, ss, mid,                                st, si * 2 + 1)         + constructSTUtil(arr, mid + 1,                           se, st,                           si * 2 + 2);       return st[si];     } Â
    // Function to construct segment     // tree from given array     function constructST(arr, n)     {       // Allocate memory for the segment tree Â
      // Height of segment tree       let x = parseInt((Math.ceil(Math.log(n)/Math.log(2))), 10); Â
      // Maximum size of segment tree       let max_size = 2 * Math.pow(2, x) - 1; Â
      // Allocate memory       let st = new Array(max_size); Â
      // Fill the allocated memory st       constructSTUtil(arr, 0, n - 1, st, 0); Â
      // Return the constructed segment tree       return st;     }          let arr = [ 1, 3, 5, 7, 9, 11 ];     let n = arr.length;       let Q = [ [ 1, 1, 3 ],                [ 2, 1, 10 ],                [ 1, 1, 3 ] ];       // Function call     SieveOfEratosthenes();       // Build segment tree from given array     let st = constructST(arr, n);       // Print sum of values in     // array from index 1 to 3     document.write(getSum(st, n, 1, 3) + "</br>" );       // Update: set arr[1] = 10     // and update corresponding     // segment tree nodes     updateValue(arr, st, n, 1, 10);       // Find sum after the value is updated     document.write(getSum(st, n, 1, 3) + "</br>" );        // This code is contributed by mukesh07. </script> |
15 12
Â
Time Complexity: O(MAX*log(log(MAX))+Q * log N)Â
Auxiliary Space: O(N)
Â
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!