Skip to content
Related Articles
Get the best out of our app
GeeksforGeeks App
Open App
geeksforgeeks
Browser
Continue

Related Articles

Queries to calculate sum of squares of ASCII values of characters of a substring with updates

Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article

Given a string S of length N and a 2D array of strings Q[][] consisting of M queries of the following type:

  • Query(“U”, “I”, “X”): Update the character at index I with the character X.
  • Query(“S”, “L”, “R”): Print the sum of the squares of the position of the characters in the substring {S[L], …., S[R]} according to the English alphabets.

Examples:

Input: S = “geeksforgeeks”, Q[][] = {{“S”, “0”, “2”}, {“S”, “1”, “2”}, {“U”, “1”, “a”}, {“S”, “0”, “2”}, {“S”, “4”, “5”}}
Output: 
99
50
75
397
Explanation:
For Query(“S”, “0”, “2”), sum of squares of the positions of the characters in the substring “gee” = 7*7 + 5*5 + 5*5 = 99.
For Query(“S”, “1”, “2”), sum of squares of the positions of the character in the substring “ee” = 5*5 + 5*5 = 50.
For Query(“U”, “1”, “a”): Replacing S[1] by ‘a’ modifies S to “gaeksforgeeks”.
For Query(“S”, “0”, “2”), sum of squares of the positions of the characters in the substring “gae” = 7*7 + 1*1 + 5*5 = 75.
For Query(“S”, “4”, “5”), sum of squares of the positions of the characters in the substring “ks” = 19*19 + 36 = 397

Input: S = “geeksforgeeks”, Q[][] = {{“S”, “1”, “2”}}
Output: 50

Naive Approach: The simplest approach to solve the problem is to traverse the array Q[][] for each query and for queries of type ‘S’, simply traverse the substring {S[L], …, S[R]} and print the sum of squares of the positions of the characters in English alphabets. In each iteration to perform the query of type ‘U’, simply assign X to S[I]. 

Time Complexity: O(N * M)
Auxiliary Space: O(1)

Efficient Approach: The above approach can be optimized by using Segment Tree data structure. Follow the steps below to solve the problem:

  • Initialize a segment tree, say tree[], where each node stores the sum of squares of the position of the characters in English alphabets in its subtree.
  • For Query(“U”, “I”, “X”), define an update function, similar to the update function of sum range queries. Update S[i] = X and then call the update() function to update the segment tree.
  • For Query(“S”, “L”, “R”), define a function query(), similar to sum range query and then, print the sum obtained by calling the query() function for the substring {S[L], …., S[R]}.

Below is the implementation of the above approach:

C++




// C++ implementation of
// the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Structure of a node
// of a Segment Tree
struct treeNode {
    int square_sum;
};
 
// Function to construct the Segment Tree
void buildTree(string s, treeNode* tree,
               int start, int end,
               int treeNode)
{
    // If start and end are equal
    if (start == end) {
 
        // Assign squares of positions
        // of the characters
        tree[treeNode].square_sum
            = pow(s[start] - 'a' + 1, 2);
 
        return;
    }
 
    // Stores the mid value of
    // the range [start, end]
    int mid = start + ((end - start) / 2);
 
    // Recursive call to left subtree
    buildTree(s, tree, start,
              mid, 2 * treeNode);
 
    // Recursive call to right subtree
    buildTree(s, tree, mid + 1,
              end, 1 + 2 * treeNode);
 
    // Update the current node
    tree[treeNode].square_sum
        = tree[(2 * treeNode)].square_sum
          + tree[(2 * treeNode) + 1].square_sum;
}
 
// Function to perform the queries of type 2
int querySquareSum(treeNode* tree, int start,
                   int end, int treeNode,
                   int l, int r)
{
    // No overlap
    if ((l > end) || (r < start)) {
        return 0;
    }
 
    // If l <= start and r >= end
    if ((l <= start) && (r >= end)) {
 
        // Return the value of treeNode
        return tree[treeNode].square_sum;
    }
 
    // Calculate middle of the range [start, end]
    int mid = start + ((end - start) / 2);
 
    // Function call to left subtree
    int X = querySquareSum(tree, start,
                           mid, 2 * treeNode,
                           l, r);
 
    // Function call to right subtree
    int Y = +querySquareSum(tree, mid + 1, end,
                            1 + 2 * treeNode, l, r);
 
    // Return the sum of X and Y
    return X + Y;
}
 
// Function to perform update
// queries on a Segment Tree
void updateTree(string s, treeNode* tree,
                int start, int end,
                int treeNode, int idx, char X)
{
    // If start is equal to end
    // and idx is equal to start
    if ((start == end) && (idx == start)) {
 
        // Base Case
        s[idx] = X;
        tree[treeNode].square_sum
            = pow(X - 'a' + 1, 2);
 
        return;
    }
 
    // Calculate middle of the range [start, end]
    int mid = start + ((end - start) / 2);
 
    // If idx <=  mid
    if (idx <= mid) {
 
        // Function call to left subtree
        updateTree(s, tree, start, mid,
                   (2 * treeNode), idx, X);
    }
 
    // Otherwise
    else {
 
        // Function call to the right subtree
        updateTree(s, tree, mid + 1, end,
                   (2 * treeNode) + 1, idx, X);
    }
 
    // Update the current node
    tree[treeNode].square_sum
        = tree[(2 * treeNode)].square_sum
          + tree[(2 * treeNode) + 1].square_sum;
}
 
// Function to perform the given queries
void PerformQuery(string S,
                  vector<vector<string> > Q)
{
    int n = S.size();
 
    // Stores the segment tree
    treeNode* tree = new treeNode[(4 * n) + 1];
 
    // Traverse the segment tree
    for (int i = 0; i <= (4 * n); i = i + 1) {
 
        // Assign 0 to each node
        tree[i].square_sum = 0;
    }
 
    // Builds segment tree
    buildTree(S, tree, 0, n - 1, 1);
 
    // Traverse the query array Q[][]
    for (int i = 0; i < Q.size(); i++) {
 
        // If query is of type S
        if (Q[i][0] == "S") {
 
            // Stores the left boundary
            int L = stoi(Q[i][1]);
 
            // Stores the right boundary
            int R = stoi(Q[i][2]);
 
            // Prints the sum of squares of the
            // alphabetic positions of the characters
            cout << querySquareSum(tree, 0,
                                   n - 1, 1, L, R)
                 << endl;
        }
 
        // Otherwise
        else if (Q[i][0] == "U") {
 
            // Stores the index of the
            // character to be updated
            int I = stoi(Q[i][1]);
 
            // Update the segment tree
            updateTree(S, tree, 0, n - 1,
                       1, I, Q[i][2][0]);
        }
    }
}
 
// Driver Code
int main()
{
    // Input
    string S = "geeksforgeeks";
    vector<vector<string> > Q = { { "S", "0", "2" },
                                  { "S", "1", "2" },
                                  { "U", "1", "a" },
                                  { "S", "0", "2" },
                                  { "S", "4", "5" } };
    // Function call
    PerformQuery(S, Q);
}

Java




// Java implementation of
// the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
 
class GFG{
 
// Structure of a node
// of a Segment Tree
static class treeNode
{
    int square_sum;
 
    treeNode(int square_sum)
    {
        this.square_sum = square_sum;
    }
};
 
// Function to construct the Segment Tree
static void buildTree(char s[], treeNode tree[],
                      int start, int end, int treenode)
{
     
    // If start and end are equal
    if (start == end)
    {
         
        // Assign squares of positions
        // of the characters
        tree[treenode].square_sum = (int)Math.pow(
            s[start] - 'a' + 1, 2);
 
        return;
    }
 
    // Stores the mid value of
    // the range [start, end]
    int mid = start + ((end - start) / 2);
 
    // Recursive call to left subtree
    buildTree(s, tree, start, mid, 2 * treenode);
 
    // Recursive call to right subtree
    buildTree(s, tree, mid + 1, end, 1 + 2 * treenode);
 
    // Update the current node
    tree[treenode].square_sum = tree[(2 * treenode)].square_sum +
                                tree[(2 * treenode) + 1].square_sum;
}
 
// Function to perform the queries of type 2
static int querySquareSum(treeNode tree[], int start,
                          int end, int treenode, int l,
                          int r)
{
     
    // No overlap
    if ((l > end) || (r < start))
    {
        return 0;
    }
 
    // If l <= start and r >= end
    if ((l <= start) && (r >= end))
    {
 
        // Return the value of treeNode
        return tree[treenode].square_sum;
    }
 
    // Calculate middle of the range [start, end]
    int mid = start + ((end - start) / 2);
 
    // Function call to left subtree
    int X = querySquareSum(tree, start, mid,
                           2 * treenode, l, r);
 
    // Function call to right subtree
    int Y = +querySquareSum(tree, mid + 1, end,
                            1 + 2 * treenode, l, r);
 
    // Return the sum of X and Y
    return X + Y;
}
 
// Function to perform update
// queries on a Segment Tree
static void updateTree(char s[], treeNode tree[],
                       int start, int end, int treenode,
                       int idx, char X)
{
     
    // If start is equal to end
    // and idx is equal to start
    if ((start == end) && (idx == start))
    {
         
        // Base Case
        s[idx] = X;
        tree[treenode].square_sum = (int)Math.pow(
            X - 'a' + 1, 2);
 
        return;
    }
 
    // Calculate middle of the range [start, end]
    int mid = start + ((end - start) / 2);
 
    // If idx <=  mid
    if (idx <= mid)
    {
         
        // Function call to left subtree
        updateTree(s, tree, start, mid, (2 * treenode),
                   idx, X);
    }
 
    // Otherwise
    else
    {
 
        // Function call to the right subtree
        updateTree(s, tree, mid + 1, end,
                 (2 * treenode) + 1, idx, X);
    }
 
    // Update the current node
    tree[treenode].square_sum = tree[(2 * treenode)].square_sum +
                                tree[(2 * treenode) + 1].square_sum;
}
 
// Function to perform the given queries
static void PerformQuery(String S, String Q[][])
{
    int n = S.length();
 
    // Stores the segment tree
    treeNode tree[] = new treeNode[(4 * n) + 1];
 
    // Traverse the segment tree
    for(int i = 0; i <= (4 * n); i = i + 1)
    {
         
        // Assign 0 to each node
        tree[i] = new treeNode(0);
    }
 
    char s[] = S.toCharArray();
 
    // Builds segment tree
    buildTree(s, tree, 0, n - 1, 1);
 
    // Traverse the query array Q[][]
    for(int i = 0; i < Q.length; i++)
    {
         
        // If query is of type S
        if (Q[i][0] == "S")
        {
             
            // Stores the left boundary
            int L = Integer.parseInt(Q[i][1]);
 
            // Stores the right boundary
            int R = Integer.parseInt(Q[i][2]);
 
            // Prints the sum of squares of the
            // alphabetic positions of the characters
            System.out.println(querySquareSum(
                tree, 0, n - 1, 1, L, R));
        }
 
        // Otherwise
        else if (Q[i][0] == "U")
        {
             
            // Stores the index of the
            // character to be updated
            int I = Integer.parseInt(Q[i][1]);
 
            // Update the segment tree
            updateTree(s, tree, 0, n - 1, 1, I,
                       Q[i][2].charAt(0));
        }
    }
}
 
// Driver Code
public static void main(String[] args)
{
 
    // Input
    String S = "geeksforgeeks";
    String Q[][] = { { "S", "0", "2" },
                     { "S", "1", "2" },
                     { "U", "1", "a" },
                     { "S", "0", "2" },
                     { "S", "4", "5" } };
    // Function call
    PerformQuery(S, Q);
}
}
 
// This code is contributed by Kingash

Python3




# Python3 implementation of
# the above approach
 
# Structure of a node
# of a Segment Tree
class treeNode:
     
    def __init__(self, x):
         
        self.square_sum = x
 
# Function to construct the Segment Tree
def buildTree(s, tree, start, end, treeNode):
     
    # If start and end are equa
    if (start == end):
 
        # Assign squares of positions
        # of the characters
        tree[treeNode].square_sum = pow(ord(s[start]) -
                                        ord('a') + 1, 2)
 
        return
 
    # Stores the mid value of
    # the range [start, end]
    mid = start + ((end - start) // 2)
 
    # Recursive call to left subtree
    buildTree(s, tree, start, mid, 2 * treeNode)
 
    # Recursive call to right subtree
    buildTree(s, tree, mid + 1, end,
                         1 + 2 * treeNode)
 
    # Update the current node
    tree[treeNode].square_sum = (tree[(2 * treeNode)].square_sum +
                                 tree[(2 * treeNode) + 1].square_sum)
 
# Function to perform the queries of type 2
def querySquareSum(tree, start, end, treeNode, l, r):
     
    # No overlap
    if ((l > end) or (r < start)):
        return 0
 
    # If l <= start and r >= end
    if ((l <= start) and (r >= end)):
         
        # Return the value of treeNode
        return tree[treeNode].square_sum
 
    # Calculate middle of the range [start, end]
    mid = start + ((end - start) // 2)
 
    # Function call to left subtree
    X = querySquareSum(tree, start, mid,
                       2 * treeNode, l, r)
 
    # Function call to right subtree
    Y = +querySquareSum(tree, mid + 1, end,
                                1 + 2 * treeNode, l, r)
 
    # Return the sum of X and Y
    return X + Y
 
# Function to perform update
# queries on a Segment Tree
def updateTree(s, tree, start, end, treeNode, idx, X):
     
    # If start is equal to end
    # and idx is equal to start
    if ((start == end) and (idx == start)):
 
        # Base Case
        s[idx] = X
        tree[treeNode].square_sum = pow(ord(X) -
                                       ord('a') + 1, 2)
        return
 
    # Calculate middle of the range [start, end]
    mid = start + ((end - start) // 2)
 
    # If idx <=  mid
    if (idx <= mid):
         
        # Function call to left subtree
        updateTree(s, tree, start, mid,
                  (2 * treeNode), idx, X)
                   
    # Otherwise
    else:
 
        # Function call to the right subtree
        updateTree(s, tree, mid + 1, end,
                  (2 * treeNode) + 1, idx, X)
 
    # Update the current node
    tree[treeNode].square_sum = (tree[(2 * treeNode)].square_sum +
                                 tree[(2 * treeNode) + 1].square_sum)
 
# Function to perform the given queries
def PerformQuery(S, Q):
     
    n = len(S)
 
    # Stores the segment tree
    tree = [treeNode(0) for i in range((4 * n) + 1)]
 
    # Traverse the segment tree
    for i in range(4 * n + 1):
         
        # Assign 0 to each node
        tree[i].square_sum = 0
 
    # Builds segment tree
    buildTree(S, tree, 0, n - 1, 1)
 
    # Traverse the query array Q[][]
    for i in range(len(Q)):
         
        # If query is of type S
        if (Q[i][0] == "S"):
             
            # Stores the left boundary
            L = int(Q[i][1])
 
            # Stores the right boundary
            R = int(Q[i][2])
 
            # Prints the sum of squares of the
            # alphabetic positions of the characters
            print(querySquareSum(tree, 0, n - 1,
                                 1, L, R))
 
        # Otherwise
        elif (Q[i][0] == "U"):
 
            # Stores the index of the
            # character to be updated
            I = int(Q[i][1])
 
            # Update the segment tree
            updateTree(S, tree, 0, n - 1,
                       1, I, Q[i][2][0])
 
# Driver Code
if __name__ == '__main__':
     
    # Input
    S = "geeksforgeeks"
    Q = [ [ "S", "0", "2" ],
          [ "S", "1", "2" ],
          [ "U", "1", "a" ],
          [ "S", "0", "2" ],
          [ "S", "4", "5" ] ]
           
    # Function call
    PerformQuery([i for i in S], Q)
 
# This code is contributed by mohit kumar 29

C#




using System;
 
public class treeNode
{
    public int square_sum;
  
    public treeNode(int square_sum)
    {
        this.square_sum = square_sum;
    }
};
 
public class GFG{
     
    // Function to construct the Segment Tree
static void buildTree(char[] s, treeNode[] tree,
                      int start, int end, int treenode)
{
      
    // If start and end are equal
    if (start == end)
    {
          
        // Assign squares of positions
        // of the characters
        tree[treenode].square_sum = (int)Math.Pow(
            s[start] - 'a' + 1, 2);
  
        return;
    }
  
    // Stores the mid value of
    // the range [start, end]
    int mid = start + ((end - start) / 2);
  
    // Recursive call to left subtree
    buildTree(s, tree, start, mid, 2 * treenode);
  
    // Recursive call to right subtree
    buildTree(s, tree, mid + 1, end, 1 + 2 * treenode);
  
    // Update the current node
    tree[treenode].square_sum = tree[(2 * treenode)].square_sum +
                                tree[(2 * treenode) + 1].square_sum;
}
  
// Function to perform the queries of type 2
static int querySquareSum(treeNode[] tree, int start,
                          int end, int treenode, int l,
                          int r)
{
      
    // No overlap
    if ((l > end) || (r < start))
    {
        return 0;
    }
  
    // If l <= start and r >= end
    if ((l <= start) && (r >= end))
    {
  
        // Return the value of treeNode
        return tree[treenode].square_sum;
    }
  
    // Calculate middle of the range [start, end]
    int mid = start + ((end - start) / 2);
  
    // Function call to left subtree
    int X = querySquareSum(tree, start, mid,
                           2 * treenode, l, r);
  
    // Function call to right subtree
    int Y = +querySquareSum(tree, mid + 1, end,
                            1 + 2 * treenode, l, r);
  
    // Return the sum of X and Y
    return X + Y;
}
  
// Function to perform update
// queries on a Segment Tree
static void updateTree(char[] s, treeNode[] tree,
                       int start, int end, int treenode,
                       int idx, char X)
{
      
    // If start is equal to end
    // and idx is equal to start
    if ((start == end) && (idx == start))
    {
          
        // Base Case
        s[idx] = X;
        tree[treenode].square_sum = (int)Math.Pow(
            X - 'a' + 1, 2);
  
        return;
    }
  
    // Calculate middle of the range [start, end]
    int mid = start + ((end - start) / 2);
  
    // If idx <=  mid
    if (idx <= mid)
    {
          
        // Function call to left subtree
        updateTree(s, tree, start, mid, (2 * treenode),
                   idx, X);
    }
  
    // Otherwise
    else
    {
  
        // Function call to the right subtree
        updateTree(s, tree, mid + 1, end,
                 (2 * treenode) + 1, idx, X);
    }
  
    // Update the current node
    tree[treenode].square_sum = tree[(2 * treenode)].square_sum +
                                tree[(2 * treenode) + 1].square_sum;
}
  
// Function to perform the given queries
static void PerformQuery(String S, String[,] Q)
{
    int n = S.Length;
  
    // Stores the segment tree
    treeNode[] tree = new treeNode[(4 * n) + 1];
  
    // Traverse the segment tree
    for(int i = 0; i <= (4 * n); i = i + 1)
    {
          
        // Assign 0 to each node
        tree[i] = new treeNode(0);
    }
  
    char[] s = S.ToCharArray();
  
    // Builds segment tree
    buildTree(s, tree, 0, n - 1, 1);
  
    // Traverse the query array Q[][]
    for(int i = 0; i < Q.GetLength(0); i++)
    {
          
        // If query is of type S
        if (Q[i,0] == "S")
        {
              
            // Stores the left boundary
            int L = Int32.Parse(Q[i,1]);
  
            // Stores the right boundary
            int R = Int32.Parse(Q[i,2]);
  
            // Prints the sum of squares of the
            // alphabetic positions of the characters
            Console.WriteLine(querySquareSum(
                tree, 0, n - 1, 1, L, R));
        }
  
        // Otherwise
        else if (Q[i,0] == "U")
        {
              
            // Stores the index of the
            // character to be updated
            int I = Int32.Parse(Q[i,1]);
  
            // Update the segment tree
            updateTree(s, tree, 0, n - 1, 1, I,
                       Q[i,2][0]);
        }
    }
}
  
// Driver Code
     
    static public void Main (){
         
        // Input
    string S = "geeksforgeeks";
    string[,] Q = { { "S", "0", "2" },
                     { "S", "1", "2" },
                     { "U", "1", "a" },
                     { "S", "0", "2" },
                     { "S", "4", "5" } };
    // Function call
    PerformQuery(S, Q);
         
    }
}
 
// This code is contributed by unknown2108.

Javascript




<script>
// Javascript implementation of
// the above approach
 
// Structure of a node
// of a Segment Tree
class treeNode
{
    constructor( square_sum)
    {
        this.square_sum = square_sum;
    }
}
 
// Function to construct the Segment Tree
function buildTree(s,tree,start,end,treenode)
{
    // If start and end are equal
    if (start == end)
    {
          
        // Assign squares of positions
        // of the characters
        tree[treenode].square_sum = Math.pow(
            s[start].charCodeAt(0) - 'a'.charCodeAt(0) + 1, 2);
  
        return;
    }
  
    // Stores the mid value of
    // the range [start, end]
    let mid = start + Math.floor((end - start) / 2);
  
    // Recursive call to left subtree
    buildTree(s, tree, start, mid, 2 * treenode);
  
    // Recursive call to right subtree
    buildTree(s, tree, mid + 1, end, 1 + 2 * treenode);
  
    // Update the current node
    tree[treenode].square_sum = tree[(2 * treenode)].square_sum +
                                tree[(2 * treenode) + 1].square_sum;
}
 
// Function to perform the queries of type 2
function  querySquareSum(tree,start,end,treenode,l,r)
{
    // No overlap
    if ((l > end) || (r < start))
    {
        return 0;
    }
  
    // If l <= start and r >= end
    if ((l <= start) && (r >= end))
    {
  
        // Return the value of treeNode
        return tree[treenode].square_sum;
    }
  
    // Calculate middle of the range [start, end]
    let mid = start + Math.floor((end - start) / 2);
  
    // Function call to left subtree
    let X = querySquareSum(tree, start, mid,
                           2 * treenode, l, r);
  
    // Function call to right subtree
    let Y = +querySquareSum(tree, mid + 1, end,
                            1 + 2 * treenode, l, r);
  
    // Return the sum of X and Y
    return X + Y;
}
 
// Function to perform update
// queries on a Segment Tree
function updateTree(s,tree,start,end,treenode,idx,X)
{
    // If start is equal to end
    // and idx is equal to start
    if ((start == end) && (idx == start))
    {
          
        // Base Case
        s[idx] = X;
        tree[treenode].square_sum = Math.pow(
            X.charCodeAt(0) - 'a'.charCodeAt(0) + 1, 2);
  
        return;
    }
  
    // Calculate middle of the range [start, end]
    let mid = start + Math.floor((end - start) / 2);
  
    // If idx <=  mid
    if (idx <= mid)
    {
          
        // Function call to left subtree
        updateTree(s, tree, start, mid, (2 * treenode),
                   idx, X);
    }
  
    // Otherwise
    else
    {
  
        // Function call to the right subtree
        updateTree(s, tree, mid + 1, end,
                 (2 * treenode) + 1, idx, X);
    }
  
    // Update the current node
    tree[treenode].square_sum = tree[(2 * treenode)].square_sum +
                                tree[(2 * treenode) + 1].square_sum;
}
 
// Function to perform the given queries
function PerformQuery(S,Q)
{
     let n = S.length;
  
    // Stores the segment tree
    let tree = new Array((4 * n) + 1);
  
    // Traverse the segment tree
    for(let i = 0; i <= (4 * n); i = i + 1)
    {
          
        // Assign 0 to each node
        tree[i] = new treeNode(0);
    }
  
    let s = S.split("");
  
    // Builds segment tree
    buildTree(s, tree, 0, n - 1, 1);
  
    // Traverse the query array Q[][]
    for(let i = 0; i < Q.length; i++)
    {
          
        // If query is of type S
        if (Q[i][0] == "S")
        {
              
            // Stores the left boundary
            let L = parseInt(Q[i][1]);
  
            // Stores the right boundary
            let R = parseInt(Q[i][2]);
  
            // Prints the sum of squares of the
            // alphabetic positions of the characters
            document.write(querySquareSum(
                tree, 0, n - 1, 1, L, R)+"<br>");
        }
  
        // Otherwise
        else if (Q[i][0] == "U")
        {
              
            // Stores the index of the
            // character to be updated
            let I = parseInt(Q[i][1]);
  
            // Update the segment tree
            updateTree(s, tree, 0, n - 1, 1, I,
                       Q[i][2][0]);
        }
    }
}
 
// Driver Code
let S = "geeksforgeeks";
 
let Q=[[ "S", "0", "2" ],
                     [ "S", "1", "2" ],
                     [ "U", "1", "a" ],
                     [ "S", "0", "2" ],
                     [ "S", "4", "5" ]]
// Function call
PerformQuery(S, Q);
 
// This code is contributed by patel2127
</script>

Output: 

99
50
75
397

 

Time Complexity: O((N + M) * log N)
Auxiliary Space: O(N)

 


My Personal Notes arrow_drop_up
Last Updated : 05 Jul, 2021
Like Article
Save Article
Similar Reads
Related Tutorials