Open In App

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) = 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++ 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 queries
void 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 code
int 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 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<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 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 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# 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

                    
<script>
 
// Javascript implementation to find
// sum of product of every number
// and square of its frequency
// in the given range
 
// Function to solve queries
function 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 code
var 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>

                    

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.

Below is the implementation of the above approach:

// 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 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<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 Code
int 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);
}

                    
/*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 implementation to find sum
# of product of every number
# and square of its frequency
# in the given range
import functools
 
# Stores frequency
N = 10 ** 5 + 5;
 
# Frequency array
freq = [0 for _ in range(N)]
 
sq = 0;
 
# Function for comparator
def 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 range
def 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 queries
def 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 Code
arr = [ 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.

                    
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.

                    
// JS implementation to find sum
// of product of every number
// and square of its frequency
// in the given range
 
 
 
// Stores frequency
let N = 1e5 + 5;
 
// Frequency array
let freq = new Array(N).fill(0);
 
let sq;
 
// Function for comparator
function 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 range
function 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 queries
function 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 Code
let arr = [ 1, 1, 2, 2, 1, 3, 1, 1 ];
 
let n = arr.length;
 
let queries = [[2, 7 ], [ 1, 6 ] ];
answerQueries(arr, n, queries);

                    

Output: 
10
10

 

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


Article Tags :