Find sum of product of every number and its frequency in given range

• Difficulty Level : Hard
• Last Updated : 10 Jun, 2021

Given an array arr[] of integers and an array of queries, the task is to find the sum of product of every number and its frequency in given range [L, R] where each ranges are given in the array of queries.

Examples:

Input: arr[] = [1, 2, 1], Queries: [{1, 2}, {1, 3}]
Output: [3, 4]
Explanation:
For query [1, 2], freq = 1, freq = 1, ans = (1 * freq) + (2 * freq) => ans = (1 * 1 + 2 * 1) = 3
For query [1, 3], freq = 2, freq = 1; ans = (1 * freq) + (2 * freq) => ans = (1 * 2) + (2 * 1) = 4

Input: arr[] = [1, 1, 2, 2, 1, 3, 1, 1], Queries: [{2, 7}, {1, 6}]
Output: [10, 10]
Explanation:
For query (2, 7), freq = 3, freq = 2, freq = 3;
ans = (1 * freq) + (2 * freq ) + (3 * freq)
ans = (1 * 3) + (2 * 2) + (3 * 1) = 10

Naive Approach:
To solve the problem mentioned above the naive method is to iterate over the subarray given in the query. Maintain a map for the frequency of each number in the subarray and iterate over the map and compute the answer.

Below is the implementation of the above approach:

C++

 // C++ implementation to find// sum of product of every number// and square of its frequency// in the given range #include using namespace std; // Function to solve queriesvoid answerQueries(    int arr[], int n,    vector >& queries){     for (int i = 0; i < queries.size(); i++) {         // Calculating answer        // for every query        int ans = 0;         // The end points        // of the ith query        int l = queries[i].first - 1;        int r = queries[i].second - 1;         // map for storing frequency        map freq;        for (int j = l; j <= r; j++) {             // Iterating over the given            // subarray and storing            // frequency in a map             // Incrementing the frequency            freq[arr[j]]++;        }         // Iterating over map to find answer        for (auto& i : freq) {             // adding the contribution            // of ith number            ans += (i.first                    * i.second);        }         // print answer        cout << ans << endl;    }} // Driver codeint main(){     int arr[] = { 1, 2, 1 };    int n = sizeof(arr) / sizeof(arr);     vector > queries        = { { 1, 2 },            { 1, 3 } };    answerQueries(arr, n, queries);}

Java

 // Java program to find sum of// product of every number and// square of its frequency in// the given rangeimport java.util.*; class GFG{ // Function to solve queries    public static void answerQueries(int[] arr,                                 int n,                                 int[][] queries){    for(int i = 0; i < queries.length; i++)    {                 // Calculating answer        // for every query            int ans = 0;         // The end points        // of the ith query        int l = queries[i] - 1;        int r = queries[i] - 1;         // Hashmap for storing frequency        Map freq = new HashMap<>();         for(int j = l; j < r + 1; j++)        {                         // Iterating over the given            // subarray and storing            // frequency in a map             // Incrementing the frequency            freq.put(arr[j],                     freq.getOrDefault(arr[j], 0) + 1);        }        for(int k: freq.keySet())        {                         // Adding the contribution            // of ith number            ans += k * freq.get(k);        }             // Print answer    System.out.println(ans);    }} // Driver codepublic static void main(String args[] ){    int[] arr = { 1, 2, 1 };    int n = arr.length;    int[][] queries = { { 1, 2 },                        { 1, 3 } };                             // Calling function    answerQueries(arr, n, queries);}} // This code contributed by dadi madhav

Python3

 # Python3 implementation to find# sum of product of every number# and square of its frequency# in the given range # Function to solve queriesdef answerQueries(arr, n, queries):         for i in range(len(queries)):         # Calculating answer        # for every query        ans = 0         # The end points        # of the ith query        l = queries[i] - 1        r = queries[i] - 1         # Map for storing frequency        freq = dict()        for j in range(l, r + 1):             # Iterating over the given            # subarray and storing            # frequency in a map             # Incrementing the frequency            freq[arr[j]] = freq.get(arr[j], 0) + 1         # Iterating over map to find answer        for i in freq:             # Adding the contribution            # of ith number            ans += (i * freq[i])         # Print answer        print(ans) # Driver codeif __name__ == '__main__':         arr = [ 1, 2, 1 ]    n = len(arr)     queries = [ [ 1, 2 ],                [ 1, 3 ] ]                     answerQueries(arr, n, queries) # This code is contributed by mohit kumar 29

C#

 // C# program to find sum of// product of every number and // square of its frequency in // the given rangeusing System;using System.Collections.Generic; class GFG{     // Function to solve queriespublic static void answerQueries(int[] arr, int n,                                 int[,] queries){    for(int i = 0; i < queries.GetLength(0); i++)    {                 // Calculating answer         // for every query         int ans = 0;                 // The end points         // of the ith query        int l = queries[i, 0] - 1;        int r = queries[i, 1] - 1;                 // Hashmap for storing frequency        Dictionary freq = new Dictionary();        for(int j = l; j < r+ 1; j++)        {                         // Iterating over the given             // subarray and storing             // frequency in a map              // Incrementing the frequency            freq[arr[j]] = freq.GetValueOrDefault(arr[j], 0) + 1;        }        foreach(int k in freq.Keys)        {                         // Adding the contribution             // of ith number            ans += k * freq[k];        }                 // Print answer        Console.WriteLine(ans);    }} // Driver codestatic public void Main(){    int[] arr = { 1, 2, 1 };    int n = arr.Length;    int[,] queries = { { 1, 2 }, { 1, 3 } };         // Calling function    answerQueries(arr, n, queries);}} // This code is contributed by avanitrachhadiya2155

Javascript


Output:
3
4

Time Complexity: O(Q * N)
Auxiliary Space Complexity: O(N)

Efficient Approach:
To optimize the above method we will try to implement the problem using Mo’s Algorithm.

• Sort the queries first according to their block of size using custom comparator and also store the indexes of each query in a map for printing in order.
• Now, we will maintain two-pointer L and R which we iterate over the array for answering the queries. As we move the pointers, if we are adding some number in our range, we’ll first remove the contribution of its previous freq from the answer, then increment the frequency and finally add the contribution of new frequency in answer.
• And if we remove some element from the range, we’ll do the same, remove the contribution of existing freq of this number, decrement the freq, add the contribution of its new frequency.

Below is the implementation of the above approach:

C++

Output:
10
10

Time Complexity: O(N * sqrt{N})
Auxiliary Space Complexity: O(N)

My Personal Notes arrow_drop_up