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

C++

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


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python program to calculate the number
# pairs satisfying th condition
  
import bisect
  
# function to calculate the number of pairs
def countPairs(a, n, x, k):
    a.sort()
  
    # traverse through all elements
    ans = 0
    for i in range(n):
  
        # current number's divisor
        d = (a[i] - 1) // x
  
        # use binary search to find the element
        # after k multiples of x
        it1 = bisect.bisect_left(a, max((d + k) * x, a[i]))
  
        # use binary search to find the element
        # after k+1 multiples of x so that we get
        # the answer bu subtracting
        it2 = bisect.bisect_left(a, max((d + k + 1) * x, a[i]))
  
        # the difference of index will be the answer
        ans += it2 - it1
  
    return ans
  
# Driver code
if __name__ == "__main__":
    a = [1, 3, 5, 7]
    n = len(a)
    x = 2
    k = 1
  
    # function call to get the number of pairs
    print(countPairs(a, n, x, k))
  
# This code is contributed by
# sanjeev2552

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.



Improved By : sanjeev2552, Akanksha_Rai