Welcome to Subscribe On Youtube
1862. Sum of Floored Pairs
Description
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. Since the answer may be too large, return it modulo 109 + 7
.
The floor()
function returns the integer part of the division.
Example 1:
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.
Example 2:
Input: nums = [7,7,7,7,7,7,7] Output: 49
Constraints:
1 <= nums.length <= 105
1 <= nums[i] <= 105
Solutions
Solution 1: Prefix Sum of Value Range + Optimized Enumeration
First, we count the occurrences of each element in the array $nums$ and record them in the array $cnt$. Then, we calculate the prefix sum of the array $cnt$ and record it in the array $s$, i.e., $s[i]$ represents the count of elements less than or equal to $i$.
Next, we enumerate the denominator $y$ and the quotient $d$. Using the prefix sum array, we can calculate the count of the numerator $s[\min(mx, d \times y + y - 1)] - s[d \times y - 1]$, where $mx$ represents the maximum value in the array $nums$. Then, we multiply the count of the numerator by the count of the denominator $cnt[y]$, and then multiply by the quotient $d$. This gives us the value of all fractions that meet the conditions. By summing these values, we can get the answer.
The time complexity is $O(M \times \log M)$, and the space complexity is $O(M)$. Here, $M$ is the maximum value in the array $nums$.
-
class Solution { public int sumOfFlooredPairs(int[] nums) { final int mod = (int) 1e9 + 7; int mx = 0; for (int x : nums) { mx = Math.max(mx, x); } int[] cnt = new int[mx + 1]; int[] s = new int[mx + 1]; for (int x : nums) { ++cnt[x]; } for (int i = 1; i <= mx; ++i) { s[i] = s[i - 1] + cnt[i]; } long ans = 0; for (int y = 1; y <= mx; ++y) { if (cnt[y] > 0) { for (int d = 1; d * y <= mx; ++d) { ans += 1L * cnt[y] * d * (s[Math.min(mx, d * y + y - 1)] - s[d * y - 1]); ans %= mod; } } } return (int) ans; } }
-
class Solution { public: int sumOfFlooredPairs(vector<int>& nums) { const int mod = 1e9 + 7; int mx = *max_element(nums.begin(), nums.end()); vector<int> cnt(mx + 1); vector<int> s(mx + 1); for (int x : nums) { ++cnt[x]; } for (int i = 1; i <= mx; ++i) { s[i] = s[i - 1] + cnt[i]; } long long ans = 0; for (int y = 1; y <= mx; ++y) { if (cnt[y]) { for (int d = 1; d * y <= mx; ++d) { ans += 1LL * cnt[y] * d * (s[min(mx, d * y + y - 1)] - s[d * y - 1]); ans %= mod; } } } return ans; } };
-
class Solution: def sumOfFlooredPairs(self, nums: List[int]) -> int: mod = 10**9 + 7 cnt = Counter(nums) mx = max(nums) s = [0] * (mx + 1) for i in range(1, mx + 1): s[i] = s[i - 1] + cnt[i] ans = 0 for y in range(1, mx + 1): if cnt[y]: d = 1 while d * y <= mx: ans += cnt[y] * d * (s[min(mx, d * y + y - 1)] - s[d * y - 1]) ans %= mod d += 1 return ans
-
func sumOfFlooredPairs(nums []int) (ans int) { mx := slices.Max(nums) cnt := make([]int, mx+1) s := make([]int, mx+1) for _, x := range nums { cnt[x]++ } for i := 1; i <= mx; i++ { s[i] = s[i-1] + cnt[i] } const mod int = 1e9 + 7 for y := 1; y <= mx; y++ { if cnt[y] > 0 { for d := 1; d*y <= mx; d++ { ans += d * cnt[y] * (s[min((d+1)*y-1, mx)] - s[d*y-1]) ans %= mod } } } return }
-
function sumOfFlooredPairs(nums: number[]): number { const mx = Math.max(...nums); const cnt: number[] = Array(mx + 1).fill(0); const s: number[] = Array(mx + 1).fill(0); for (const x of nums) { ++cnt[x]; } for (let i = 1; i <= mx; ++i) { s[i] = s[i - 1] + cnt[i]; } let ans = 0; const mod = 1e9 + 7; for (let y = 1; y <= mx; ++y) { if (cnt[y]) { for (let d = 1; d * y <= mx; ++d) { ans += cnt[y] * d * (s[Math.min((d + 1) * y - 1, mx)] - s[d * y - 1]); ans %= mod; } } } return ans; }
-
impl Solution { pub fn sum_of_floored_pairs(nums: Vec<i32>) -> i32 { const MOD: i32 = 1_000_000_007; let mut mx = 0; for &x in nums.iter() { mx = mx.max(x); } let mut cnt = vec![0; (mx + 1) as usize]; let mut s = vec![0; (mx + 1) as usize]; for &x in nums.iter() { cnt[x as usize] += 1; } for i in 1..=mx as usize { s[i] = s[i - 1] + cnt[i]; } let mut ans = 0; for y in 1..=mx as usize { if cnt[y] > 0 { let mut d = 1; while d * y <= (mx as usize) { ans += ((cnt[y] as i64) * (d as i64) * (s[std::cmp::min(mx as usize, d * y + y - 1)] - s[d * y - 1])) % (MOD as i64); ans %= MOD as i64; d += 1; } } } ans as i32 } }