Input: nums =[1,2,3,4,3,2,1], k =7Output: 2Explanation:
For threshold x =2, the pairs are:(3,4) where nums[3]==4 and nums[4]==3.(2,5) where nums[2]==3 and nums[5]==2.(3,5) where nums[3]==4 and nums[5]==2.(4,5) where nums[4]==3 and nums[5]==2.(1,6) where nums[1]==2 and nums[6]==1.(2,6) where nums[2]==3 and nums[6]==1.(4,6) where nums[4]==3 and nums[6]==1.(5,6) where nums[5]==2 and nums[6]==1.There are less than k inversion pairs if we choose any integer less than 2 as threshold.
Input: nums =[10,9,9,9,1], k =4Output: 8Explanation:
For threshold x =8, the pairs are:(0,1) where nums[0]==10 and nums[1]==9.(0,2) where nums[0]==10 and nums[2]==9.(0,3) where nums[0]==10 and nums[3]==9.(1,4) where nums[1]==9 and nums[4]==1.(2,4) where nums[2]==9 and nums[4]==1.(3,4) where nums[3]==9 and nums[4]==1.There are less than k inversion pairs if we choose any integer less than 8 as threshold.
We want the minimum threshold T such that the number of inversion pairs (i < j, nums[i] > nums[j] + T) is at least k. For each T, we can count such pairs efficiently using a Binary Indexed Tree (BIT) by iterating from right to left and querying how many nums[j] < nums[i] - T.
classSolution:
defminThreshold(self, nums: list[int], k: int) -> int:
vals = sorted(nums)
n = len(nums)
defcount(T: int) -> int:
bit = [0]*(n+2)
defadd(i):
i +=1while i < len(bit): bit[i] +=1; i += i &-i
defsum_(i):
i +=1; s =0while i >0: s += bit[i]; i -= i &-i
return s
cnt =0for i in range(n-1,-1,-1):
idx = bisect.bisect_left(vals, nums[i]-T)-1if idx >=0: cnt += sum_(idx)
add(bisect.bisect_left(vals, nums[i]))
return cnt
l, r =0, max(nums)
while l < r:
T = (l+r)//2if count(T) >= k: r = T
else: l = T+1return l
classSolution {
funminThreshold(nums: IntArray, k: Int): Int {
val vals = nums.sorted()
val n = nums.size
funcount(T: Int): Int {
val bit = IntArray(n+2)
funadd(i: Int) { var idx=i+1; while(idx<bit.size){bit[idx]++;idx+=idx and -idx} }
funsum(i: Int): Int { var idx=i+1; var s=0; while(idx>0){s+=bit[idx];idx-=idx and -idx}; return s }
var cnt = 0for (i in n-1 downTo 0) {
val idx = vals.binarySearch(nums[i]-T).let{if(it<0)-it-2elseit-1}
if (idx >=0) cnt += sum(idx)
add(vals.binarySearch(nums[i]).let{if(it<0)-it-1elseit})
}
return cnt
}
var l = 0; var r = nums.maxOrNull()!!while (l < r) {
val T = (l+r)/2if (count(T) >= k) r = T else l = T+1 }
return l
}
}