📜  对数(a [j]> = a [i])的对数,其中k个数在(a [i],a [j])范围内,可被x整除

📅  最后修改于: 2021-04-26 18:29:30             🧑  作者: Mango

给定一个数组和两个数字x和k。求出索引(i,j)的不同有序对的数量,使得a [j]> = a [i],并且正好有k个整数num,使得num可被x整除,并且num在a [i]-范围内a [j]。

例子:

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.

幼稚的方法是遍历所有可能的对,并计算它们之间有k个整数(可被x整除)的对的数量。
时间复杂度: O(n ^ 2)

一种有效的方法是对数组进行排序,并使用二进制搜索来找出数字的左右边界(使用lower_bound函数内置函数来完成),该数字满足条件且不满足该条件。我们必须对数组进行排序,因为给出的每对数组都应为a [j]> = a [i],而与i和j的值无关。排序后,我们遍历n个元素,并找到与x相乘得到a [i] -1的数字,以便我们可以通过将d加到d = a [i] -1 / x来找到k个数。因此,我们对值(d + k)* x进行二进制搜索,以获取可以构成一对a [i]的倍数,因为它将在a [i]和a [j]之间恰好有k个整数。这样,我们在O(log n)中使用二进制搜索获得a [j]的左边界,对于所有其他可能使用a [i]的对,我们需要通过搜索等于的数来找出最右边界等于或大于(d + k + 1)* x,我们将得到k + 1的倍数,并且得到的结对数不算为(从右到左)边界[索引方式]。

C++
// cpp program to calculate the number
// pairs satisfying th condition
#include 
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;
}


Java
// Java program to calculate the number
// pairs satisfying th condition
import java.util.*; 
  
class GFG
{
  
// function to calculate the number of pairs
static int countPairs(int a[], int n, int x, int k)
{
    Arrays.sort(a); 
  
    // 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 = Arrays.binarySearch(a, 
                    Math.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
        int it2 = Arrays.binarySearch(a,
                    Math.max((d + k + 1) * x, a[i])) ;
  
        // the difference of index will be the answer
        ans += it1 - it2;
    }
    return ans;
}
  
// Driver code 
public static void main(String[] args)
{
    int []a = { 1, 3, 5, 7 };
    int n = a.length;
    int x = 2, k = 1;
  
    // function call to get the number of pairs
    System.out.println(countPairs(a, n, x, k));
}
}
  
// This code is contributed by Rajput-Ji


Python3
# 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


输出:

3

时间复杂度: O(n log n)