Sum of Floored Pairs

By | September 27, 2023

Given an integer array nums, return the sum of floor(nums[i] / nums[j]) for all pairs of indices 0 <= i, j < nums.length in the array.
The floor() function returns the integer part of the division.

Examples:

Input: nums = [2,5,9]
Output: 10

Explanation:
floor(2 / 5) = floor(2 / 9) = floor(5 / 9) = 0
floor(2 / 2) = floor(5 / 5) = floor(9 / 9) = 1
floor(5 / 2) = 2
floor(9 / 2) = 4
floor(9 / 5) = 1
We calculate the floor of the division for every pair of indices in the array then sum them up.

Input: nums = [7,7,7,7,7,7,7]
Output: 49

Approach:
We need to observe that the result of floor(nums[i] / nums[j]), will be –

  • 0 if nums[i] < nums[j]
  • 1 if nums[j] <= nums[i] < (2 * nums[j])
  • 2 if 2 * nums[j] <= nums[i] < (3 * nums[j])
  • and so on…

We can use this to build a frequency array and then calculate the prefix sum of it.

After this, for every num in nums, we will add the answer into sum as per the above observation.

  • All the numbers in the range [0, num – 1] will contribute 0 to the sum each. The frequency of numbers in this range will be given by freq[num – 1] – freq[0].
  • All the numbers in the range [num, 2*num – 1] will contribute 1 to the sum each. Frequency: freq[num] – freq[2num – 1].
  • Numbers in [2*num, 3*num – 1] will contribute 3 each. Frequency: freq[2num] – freq[3num – 1].
  • And so on till our range covers the maximum element of the nums array…

Implementation in C++:

#include<bits/stdc++.h>
#include <iostream>

using namespace std;
const int MAXN = 1e5 + 1,
  MOD = 1e9 + 7;
  
int sumOfFlooredPairs(vector < int > & nums) {
  vector < long > freq(2 * MAXN + 1);
  long mx = 0, sum = 0;
  for (auto num: nums) ++freq[num], mx = max((int) mx, num); // counting frequency of each element in nums
  for (int i = 1; i <= 2 * MAXN; ++i) freq[i] += freq[i - 1]; // building prefix sum array of freq. Now freq[i] will hold the frequency of numbers less than or equal to i
  // Each num will be assumed in the denominator as floor(nums[i] / num) and 
  // using freq array, we can calculate the number of terms contributing 1, 2, 3... to the sum each.
  for (auto num: nums) {
    long l = num, r = 2 * num - 1, divResult = 1;
    while (l <= mx) {
      sum = (sum + divResult * (freq[r] - freq[l - 1])) % MOD;
      l += num, r += num;
      ++divResult;
    }
  }
  return sum;
}

int main() {
  vector < int > g1;
  g1.push_back(2);
  g1.push_back(5);
  g1.push_back(9);
  int ans = sumOfFlooredPairs(g1);
  cout << ans << "\n";
  return 0;
}

Output:

10 

Time Compexity: O(nlog(n))

Author: Mithlesh Upadhyay

I hold an M.Tech degree in Artificial Intelligence (2023) from Delhi Technological University (DTU) and possess over 4 years of experience. I worked at GeeksforGeeks, leading teams and managing content, including GATE CS, Test Series, Placements, C, and C++. I've also contributed technical content to companies like MarsDev, Tutorialspoint, StudyTonight, TutorialCup, and Guru99. My skill set includes coding, Data Structures and Algorithms (DSA), and Object-Oriented Programming (OOPs). I'm proficient in C++, Python, JavaScript, HTML, CSS, Bootstrap, React.js, Node.js, MongoDB, Django, and Data Science.