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

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) = 4Input: 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 <bits/stdc++.h>using namespace std;Â
// Function to solve queriesvoid answerQueries(    int arr[], int n,    vector<pair<int, int> >& 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 codeint main(){Â
    int arr[] = { 1, 2, 1 };    int n = sizeof(arr) / sizeof(arr[0]);Â
    vector<pair<int, int> > 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][0] - 1;        int r = queries[i][1] - 1;Â
        // Hashmap for storing frequency        Map<Integer,             Integer> 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][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 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 range using 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<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 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
<script>Â
// Javascript implementation to find// sum of product of every number// and square of its frequency// in the given rangeÂ
// Function to solve queriesfunction answerQueries(arr, n, queries){    for(var i = 0; i < queries.length; i++)     {                 // Calculating answer        // for every query        var ans = 0;Â
        // The end points        // of the ith query        var l = queries[i][0] - 1;        var r = queries[i][1] - 1;Â
        // map for storing frequency        var freq = new Map();        for(var j = l; j <= r; j++)         {                         // Iterating over the given            // subarray and storing            // frequency in a mapÂ
            // Incrementing the frequency            if (freq.has(arr[j]))                freq.set(arr[j], freq.get(arr[j]) + 1)            else                freq.set(arr[j], 1)        }Â
        // Iterating over map to find answer        freq.forEach((value, key) => {                         // Adding the contribution            // of ith number            ans += (key * value);        });Â
        // Print answer        document.write(ans + "<br>");    }}Â
// Driver codevar arr = [ 1, 2, 1 ];var n = arr.length;var queries = [ [ 1, 2 ],                [ 1, 3 ] ];                 answerQueries(arr, n, queries);Â
// This code is contributed by itsokÂ
</script> |
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 <bits/stdc++.h>using namespace std;Â
// Stores frequencyconst int N = 1e5 + 5;Â
// Frequency arrayvector<int> freq(N);Â
int sq;Â
// Function for comparatorbool 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 rangevoid 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 queriesvoid answerQueries(    int arr[], int n,    vector<pair<int, int> >& queries){Â
    sq = sqrt(n) + 1;Â
    vector<int> answer(        int(queries.size()));Â
    // map for storing the    // index of each query    map<pair<int, int>, 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 Codeint main(){Â
    int arr[] = { 1, 1, 2, 2, 1, 3, 1, 1 };    int n = sizeof(arr) / sizeof(arr[0]);Â
    vector<pair<int, int> > queries        = { { 2, 7 },            { 1, 6 } };    answerQueries(arr, n, queries);} |
Java
/*package whatever //do not write package name here */import java.util.*;public class GFG {Â
  static class Pair{Â
    int key;    int value;Â
    public Pair(int k, int v){      key = k;      value = v;    }Â
  }Â
  // Stores frequency  static int N = (int)1e5 + 5;Â
  // Frequency array  static int freq[] = new int[N];Â
  static int sq = 0;  static int ans = 0;Â
  // Function to add numbers in range  static void add(int x, 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]];  }Â
  static void remove(int x, 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  static void answerQueries(int arr[], int n, ArrayList<Pair> queries)  {Â
    sq = (int)Math.sqrt(n) + 1;Â
    int[] answer = new int[queries.size()];Â
    // map for storing the    // index of each query    Map<Pair, Integer> idx = new HashMap<>();Â
    // Store the index of queries    for (int i = 0; i < queries.size(); i++)      idx.put(queries.get(i),i);Â
    // Sort the queries    Collections.sort(queries,(a,b)->{      if(a.key/sq != b.key/sq) return a.key-b.key;Â
      return a.value - b.value;    });Â
    ans = 0;Â
    // pointers for iterating    // over the array    int x = 0, y = -1;    for (Pair i : queries) {Â
      // iterating over all      // the queries      int l = i.key - 1, r = i.value - 1;      int id = idx.get(i);Â
      while (x > l) {        // decrementing the left        // pointer and adding the        // xth number's contribution        x--;        add(x, arr);      }      while (y < r) {Â
        // incrementing the right        // pointer and adding the        // yth number's contribution        y++;        add(y, arr);      }      while (x < l) {Â
        // incrementing the left pointer        // and removing the        // xth number's contribution        remove(x, arr);        x++;      }      while (y > r) {Â
        // decrementing the right        // pointer and removing the        // yth number's contribution        remove(y, arr);        y--;      }      answer[id] = ans;    }Â
    // printing the answer of queries    for (int i = 0; i < queries.size(); i++)      System.out.println(answer[i]);  }Â
  public static void main (String[] args) {    int arr[] = new int[]{ 1, 1, 2, 2, 1, 3, 1, 1 };    int n = arr.length;Â
    ArrayList<Pair> queries = new ArrayList<>();    queries.add(new Pair(2,7));    queries.add(new Pair(1,6));    answerQueries(arr, n, queries);  }}Â
// This code is contributed by aadityaburujwale. |
Python3
# Python3 implementation to find sum# of product of every number# and square of its frequency# in the given rangeimport functoolsÂ
# Stores frequencyN = 10 ** 5 + 5;Â
# Frequency arrayfreq = [0 for _ in range(N)]Â
sq = 0;Â
# Function for comparatordef comparator(a, b):Â
    # comparator for sorting    # according to the which query    # lies in the which block;    if (a[0] / sq != b[0] / sq):        return a[0] > b[0];Â
    # if same block,    # return which query end first    return a[1] > b[1];Â
Â
# Function to add numbers in rangedef add(x, ans, arr):Â
    # removing contribution of    # old frequency from answerÂ
    ans -= arr[x] * freq[arr[x]];Â
    # incrementing the frequency    freq[arr[x]] += 1;Â
    # adding contribution of    # new frequency to answer    ans += arr[x] * freq[arr[x]];Â
    return ans;Â
Â
def remove(x, ans, arr):Â
    # removing contribution of    # old frequency from answer    ans -= arr[x] * freq[arr[x]];Â
    # Decrement the frequency    freq[arr[x]] -= 1;Â
    # adding contribution of    # new frequency to answer    ans += arr[x] * freq[arr[x]];Â
    return ans;Â
Â
# Function to answer the queriesdef answerQueries(arr, n, queries):Â Â Â Â global sqÂ
    sq = n ** 0.5 + 1;Â
    answer = [0 for _ in range(len(queries))] Â
    # map for storing the    # index of each query    idx = {};Â
    # Store the index of queries    for i in range(len(queries)):Â
        x = (queries[i][0], queries[i][1]);        idx[x] = i;     Â
    # Sort the queries    queries.sort( key=functools.cmp_to_key(comparator));Â
Â
    ans = 0;Â
    # pointers for iterating    # over the array    x = 0    y = -1;    for i in queries: Â
        # iterating over all        # the queries        l = i[0] - 1        r = i[1] - 1;        if (i[0], i[1]) not in idx:            idx[(i[0], i[1])] = 0;        id1 = (idx[i[0], i[1]]);Â
        while (x > l) :            # decrementing the left            # pointer and adding the            # xth number's contribution            x-=1;            ans = add(x, ans, arr);                 while (y < r) :Â
            # incrementing the right            # pointer and adding the            # yth number's contribution            y+=1;            ans = add(y, ans, arr);                 while (x < l) :Â
            # incrementing the left pointer            # and removing the            # xth number's contribution            ans = remove(x, ans, arr);            x+=1;                 while (y > r) :Â
            # decrementing the right            # pointer and removing the            # yth number's contribution            ans = remove(y, ans, arr);            y -= 1;                 answer[id1] = ans;         # printing the answer of queries    for i in range(len(queries)):        print(answer[i]);Â
# Driver Codearr = [ 1, 1, 2, 2, 1, 3, 1, 1 ];n = len(arr);Â
queries = [[2, 7 ], [ 1, 6 ] ];answerQueries(arr, n, queries);Â
# This code is contributed by phasing17. |
C#
using System;using System.Collections.Generic;Â
namespace GFG {Â Â class Program {Â
    // Stores frequency    static int N = (int)1e5 + 5;Â
    // Frequency array    static int[] freq = new int[N];Â
    static int sq = 0;    static int ans = 0;Â
    // Function to add numbers in range    static void Add(int x, 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]];    }Â
    static void Remove(int x, 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    static void AnswerQueries(int[] arr, int n,                              List<(int, int)> queries)    {      sq = (int)Math.Sqrt(n) + 1;Â
      int[] answer = new int[queries.Count];Â
      // map for storing the      // index of each query      Dictionary<(int, int), int> idx        = new Dictionary<(int, int), int>();Â
      // Store the index of queries      for (int i = 0; i < queries.Count; i++) {        idx[queries[i]] = i;      }Â
      // Sort the queries      queries.Sort((a, b) => {        if (a.Item1 / sq != b.Item1 / sq) {          return a.Item1 - b.Item1;        }Â
        return a.Item2 - b.Item2;      });Â
      ans = 0;Â
      // pointers for iterating      // over the array      int x = 0, y = -1;      foreach((int, int)i in queries)      {Â
        // iterating over all        // the queries        int l = i.Item1 - 1, r = i.Item2 - 1;        int id = idx[i];Â
        while (x > l) {Â
          // decrementing the left          // pointer and adding the          // xth number's contribution          x--;          Add(x, arr);        }        while (y < r) {Â
          // incrementing the right          // pointer and adding the          // yth number's contribution          y++;          Add(y, arr);        }        while (x < l) {Â
          // incrementing the left pointer          // and removing the          // xth number's contribution          Remove(x, arr);          x++;        }        while (y > r) {Â
          // decrementing the right          // pointer and removing the          // yth number's contribution          Remove(y, arr);          y--;        }        answer[id] = ans;      }Â
      // printing the answer of queries      foreach(int i in answer) { Console.WriteLine(i); }    }Â
    // Driver Code    static void Main(string[] args)    {      int[] arr = new int[] { 1, 1, 2, 2, 1, 3, 1, 1 };      int n = arr.Length;Â
      List<(int, int)> queries = new List<(int, int)>();      queries.Add((2, 7));      queries.Add((1, 6));      AnswerQueries(arr, n, queries);    }  }}Â
// This code is contributed by phasing17. |
Javascript
// JS implementation to find sum// of product of every number// and square of its frequency// in the given rangeÂ
Â
Â
// Stores frequencylet N = 1e5 + 5;Â
// Frequency arraylet freq = new Array(N).fill(0);Â
let sq;Â
// Function for comparatorfunction comparator(a, b){    // comparator for sorting    // according to the which query    // lies in the which block;    if (a[0] / sq != b[0] / sq)        return a[0] > b[0];Â
    // if same block,    // return which query end first    return a[1] > b[1];}Â
// Function to add numbers in rangefunction add(x, ans, 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]];Â
    return ans;}Â
function remove(x, ans, 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]];Â
    return ans;}Â
// Function to answer the queriesfunction answerQueries(arr, n, queries)Â Â Â Â Â {Â
    sq = Math.sqrt(n) + 1;Â
    let answer = new Array(queries.length).fill(0);Â
    // map for storing the    // index of each query    let idx = {};Â
    // Store the index of queries    for (var i = 0; i < queries.length; i++)    {        let x = queries[i][0] + "#" + queries[i][1];        idx[x] = i;    }Â
    // Sort the queries    queries.sort(comparator);Â
Â
    let ans = 0;Â
    // pointers for iterating    // over the array    let x = 0, y = -1;    for (let i of queries) {Â
        // iterating over all        // the queries        let l = i[0] - 1, r = i[1] - 1;        if (!idx.hasOwnProperty(i[0] + "#" + i[1]))            idx[i[0] + "#" + i[1]] = 0;        let id = idx[i[0] + "#" + i[1]];Â
        while (x > l) {            // decrementing the left            // pointer and adding the            // xth number's contribution            x--;            ans = add(x, ans, arr);        }        while (y < r) {Â
            // incrementing the right            // pointer and adding the            // yth number's contribution            y++;            ans = add(y, ans, arr);        }        while (x < l) {Â
            // incrementing the left pointer            // and removing the            // xth number's contribution            ans = remove(x, ans, arr);            x++;        }        while (y > r) {Â
            // decrementing the right            // pointer and removing the            // yth number's contribution            ans = remove(y, ans, arr);            y--;        }        answer[id] = ans;    }Â
    // printing the answer of queries         for (var i = 0; i < queries.length; i++)        console.log(answer[i]);}Â
// Driver Codelet arr = [ 1, 1, 2, 2, 1, 3, 1, 1 ];Â
let n = arr.length;Â
let queries = [[2, 7 ], [ 1, 6 ] ];answerQueries(arr, n, queries); |
10 10
Â
Time Complexity: O(N * sqrt{N})Â
Auxiliary Space Complexity: O(N)Â
Â
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



