# 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] = 1, freq[2] = 1, ans = (1 * freq[1]) + (2 * freq[2]) => ans = (1 * 1 + 2 * 1) = 3
For query [1, 3], freq[1] = 2, freq[2] = 1; ans = (1 * freq[1]) + (2 * freq[2]) => 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[1] = 3, freq[2] = 2, freq[3] = 3;
ans = (1 * freq[1]) + (2 * freq[2] ) + (3 * freq[3])
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 queries void 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<int, int> 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 code int main() {       int arr[] = { 1, 2, 1 };     int n = sizeof(arr) / sizeof(arr[0]);       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 range import 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][0] - 1;         int r = queries[i][1] - 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 code public 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 queries def 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][0] - 1         r = queries[i][1] - 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 code if __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 range  using System; using System.Collections.Generic;   class GFG{       // Function to solve queries public 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<int,                     int> freq = new Dictionary<int,                                                int>();         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 code static 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++

 // C++ implementation to find sum // of product of every number // and square of its frequency // in the given range   #include  using namespace std;   // Stores frequency const int N = 1e5 + 5;   // Frequency array vector<int> freq(N);   int sq;   // Function for comparator bool comparator(     pair<int, int>& a,     pair<int, int>& b) {     // comparator for sorting     // according to the which query     // lies in the which block;     if (a.first / sq != b.first / sq)         return a.first < b.first;       // if same block,     // return which query end first     return a.second < b.second; }   // Function to add numbers in range void add(int x, int& ans, int arr[]) {     // removing contribution of     // old frequency from answer     ans -= arr[x]            * freq[arr[x]];       // incrementing the frequency     freq[arr[x]]++;       // adding contribution of     // new frequency to answer     ans += arr[x]            * freq[arr[x]]; }   void remove(int x, int& ans, int arr[]) {     // removing contribution of     // old frequency from answer     ans -= arr[x]            * freq[arr[x]];       // Decrement the frequency     freq[arr[x]]--;       // adding contribution of     // new frequency to answer     ans += arr[x]            * freq[arr[x]]; }   // Function to answer the queries void answerQueries(     int arr[], int n,     vector >& queries) {       sq = sqrt(n) + 1;       vector<int> answer(         int(queries.size()));       // map for storing the     // index of each query     map, int> idx;       // Store the index of queries     for (int i = 0; i < queries.size(); i++)         idx[queries[i]] = i;       // Sort the queries     sort(queries.begin(),          queries.end(),          comparator);       int ans = 0;       // pointers for iterating     // over the array     int x = 0, y = -1;     for (auto& i : queries) {           // iterating over all         // the queries         int l = i.first - 1, r = i.second - 1;         int id = idx[i];           while (x > l) {             // decrementing the left             // pointer and adding the             // xth number's contribution             x--;             add(x, ans, arr);         }         while (y < r) {               // incrementing the right             // pointer and adding the             // yth number's contribution             y++;             add(y, ans, arr);         }         while (x < l) {               // incrementing the left pointer             // and removing the             // xth number's contribution             remove(x, ans, arr);             x++;         }         while (y > r) {               // decrementing the right             // pointer and removing the             // yth number's contribution             remove(y, ans, arr);             y--;         }         answer[id] = ans;     }       // printing the answer of queries     for (int i = 0; i < queries.size(); i++)         cout << answer[i] << endl; }   // Driver Code int main() {       int arr[] = { 1, 1, 2, 2, 1, 3, 1, 1 };     int n = sizeof(arr) / sizeof(arr[0]);       vector > queries         = { { 2, 7 },             { 1, 6 } };     answerQueries(arr, n, queries); }

Output:

10
10

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

My Personal Notes arrow_drop_up
Recommended Articles
Page :