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

Mithlesh Upadhyay is a Computer Science and AI expert from Madhya Pradesh with strong academic background (BE in CSE and M.Tech in AI) and over six years of experience in technical content development. He has contributed tech articles, led teams, and worked in Full Stack Development and Data Science. He founded the w3colleges.org portal for learning resources.