 GeeksforGeeks App
Open App Browser
Continue

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

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 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 ``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 > 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] == ``"S"``) {` `            ``// Stores the left boundary``            ``int` `L = stoi(Q[i]);` `            ``// Stores the right boundary``            ``int` `R = stoi(Q[i]);` `            ``// 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] == ``"U"``) {` `            ``// Stores the index of the``            ``// character to be updated``            ``int` `I = stoi(Q[i]);` `            ``// Update the segment tree``            ``updateTree(S, tree, 0, n - 1,``                       ``1, I, Q[i]);``        ``}``    ``}``}` `// Driver Code``int` `main()``{``    ``// Input``    ``string S = ``"geeksforgeeks"``;``    ``vector > 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]);``        ``}``    ``}``}`` ` `// 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

 ``

Output:

```99
50
75
397```

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

My Personal Notes arrow_drop_up