Open In App

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

Improve
Improve
Like Article
Like
Save
Share
Report

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 <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

// 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

# 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

<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.

  • Sort the queries first according to their block of \sqrt{N}                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 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);
}

                    

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 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.

                    

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 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) 
 



Last Updated : 04 Jan, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads