No of pairs (a[j] >= a[i]) with k numbers in range (a[i], a[j]) that are divisible by x

Given an array and two numbers x and k. Find the number of different ordered pairs of indexes (i, j) such that a[j] >= a[i] and there are exactly k integers num such that num is divisible by x and num is in range a[i]-a[j].

Examples:

Input : arr[] = {1, 3, 5, 7}
        x = 2, k = 1
Output : 3 
Explanation: The pairs (1, 3), (3, 5) and (5, 7) 
have k (which is 1) integers i.e., 2, 4, 6 
respectively for every pair in between them.

Input  : arr[] = {5, 3, 1, 7} 
         x = 2, k = 0 
Output : 4 
Explanation: The pairs with indexes (1, 1), (2, 2),
(3, 3), (4, 4)  have k = 0 integers that are 
divisible by 2 in between them.



A naive approach is to traverse through all pairs possible and count the number of pairs that have k integers in between them which are divisible by x.
Time complexity: O(n^2)

An efficient approach is to sort the array and use binary search to find out the right and left boundaries of numbers(use lower_bound function inbuilt function to do it) which satisfy the condition and which do not. We have to sort the array as it is given every pair should be a[j] >= a[i] irrespective of value of i and j. After sorting we traverse through n elements, and find the number with whose multiplication with x gives a[i]-1, so that we can find k number by adding k to d = a[i]-1/x. So we binary search for the value (d+k)*x to get the multiple with which we can make a pair of a[i] as it will have exactly k integers in between a[i] and a[j]. In this way we get the left boundary for a[j] using binary search in O(log n), and for all other pairs possible with a[i], we need to find out the right-most boundary by searching the the number equal to or greater then (d+k+1)*x where we will get k+1 multiples and we get the no of pairs as (right-left) boundary [index-wise].

filter_none

edit
close

play_arrow

link
brightness_4
code

// cpp program to calculate the number
// pairs satisfying th condition
#include <bits/stdc++.h>
using namespace std;
  
// function to calculate the number of pairs
int countPairs(int a[], int n, int x, int k)
{
    sort(a, a + n);    
  
    // traverse through all elements
    int ans = 0;
    for (int i = 0; i < n; i++) {
  
        // current number's divisor
        int d = (a[i] - 1) / x;
  
        // use binary search to find the element 
        // after k multiples of x
        int it1 = lower_bound(a, a + n, 
                         max((d + k) * x, a[i])) - a;
  
        // use binary search to find the element
        // after k+1 multiples of x so that we get 
        // the answer bu subtracting
        int it2 = lower_bound(a, a + n,
                     max((d + k + 1) * x, a[i])) - a;
  
        // the difference of index will be the answer
        ans += it2 - it1;
    }
    return ans;
}
  
// driver code to check the above fucntion
int main()
{
    int a[] = { 1, 3, 5, 7 };
    int n = sizeof(a) / sizeof(a[0]);
    int x = 2, k = 1;
  
    // function call to get the number of pairs
    cout << countPairs(a, n, x, k);
    return 0;
}

chevron_right


Output:

3

Time complexity: O(n log n)



My Personal Notes arrow_drop_up

Striver(underscore)79 at Codechef and codeforces D

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.