<p>You are given two <strong>0-indexed</strong> integer arrays <code>nums1</code> and <code>nums2</code>, each of size <code>n</code>, and an integer <code>diff</code>. Find the number of <strong>pairs</strong> <code>(i, j)</code> such that:</p>

<ul>
	<li><code>0 &lt;= i &lt; j &lt;= n - 1</code> <strong>and</strong></li>
	<li><code>nums1[i] - nums1[j] &lt;= nums2[i] - nums2[j] + diff</code>.</li>
</ul>

<p>Return<em> the <strong>number of pairs</strong> that satisfy the conditions.</em></p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> nums1 = [3,2,5], nums2 = [2,2,1], diff = 1
<strong>Output:</strong> 3
<strong>Explanation:</strong>
There are 3 pairs that satisfy the conditions:
1. i = 0, j = 1: 3 - 2 &lt;= 2 - 2 + 1. Since i &lt; j and 1 &lt;= 1, this pair satisfies the conditions.
2. i = 0, j = 2: 3 - 5 &lt;= 2 - 1 + 1. Since i &lt; j and -2 &lt;= 2, this pair satisfies the conditions.
3. i = 1, j = 2: 2 - 5 &lt;= 2 - 1 + 1. Since i &lt; j and -3 &lt;= 2, this pair satisfies the conditions.
Therefore, we return 3.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> nums1 = [3,-1], nums2 = [-2,2], diff = -1
<strong>Output:</strong> 0
<strong>Explanation:</strong>
Since there does not exist any pair that satisfies the conditions, we return 0.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>n == nums1.length == nums2.length</code></li>
	<li><code>2 &lt;= n &lt;= 10<sup>5</sup></code></li>
	<li><code>-10<sup>4</sup> &lt;= nums1[i], nums2[i] &lt;= 10<sup>4</sup></code></li>
	<li><code>-10<sup>4</sup> &lt;= diff &lt;= 10<sup>4</sup></code></li>
</ul>

class Solution:
    def numberOfPairs(self, nums1: List[int], nums2: List[int], diff: int) -> int:
        pass































class Solution:
    def numberOfPairs(self, nums1: List[int], nums2: List[int], diff: int) -> int:
        seen = []
        cnt = 0
        for n1, n2 in zip(nums1, nums2):
            for elem in seen:
                if n1 - n2 + diff >= elem:
                    cnt += 1
            seen.append(n1 - n2)
        return cnt


from sortedcontainers import SortedList
class Solution:
    def numberOfPairs(self, nums1: List[int], nums2: List[int], diff: int) -> int:
        seen = SortedList()
        cnt = 0
        for n1, n2 in zip(nums1, nums2):
            idx = seen.bisect_right(n1-n2+diff)
            cnt += idx
            seen.add(n1 - n2)
        return cnt









from typing import List

class Solution:
    def __init__(self):
        self.count = 0
    
    def check_count(self, nums: List[int], start: int, mid: int, end: int, d: int):
        l = start
        r = mid + 1
        
        while l <= mid and r <= end:
            if nums[l] <= nums[r] + d:
                self.count += (end - r + 1)
                l += 1
            else:
                r += 1
        
        # Sort the array from start to end
        nums[start:end + 1] = sorted(nums[start:end + 1])
    
    def merge_sort(self, nums: List[int], start: int, end: int, d: int):
        if start >= end:
            return
        
        mid = (start + end) // 2
        self.merge_sort(nums, start, mid, d)
        self.merge_sort(nums, mid + 1, end, d)
        self.check_count(nums, start, mid, end, d)
    
    def numberOfPairs(self, nums1: List[int], nums2: List[int], diff: int) -> int:
        n = len(nums1)
        c = [nums1[i] - nums2[i] for i in range(n)]
        
        self.merge_sort(c, 0, n - 1, diff)
        return self.count









from typing import List

class Solution:
    def __init__(self):
        self.count = 0
    
    def check_count(self, nums: List[int], start: int, mid: int, end: int, d: int):
        l = start
        r = mid + 1
        
        while l <= mid and r <= end:
            if nums[l] <= nums[r] + d:
                self.count += (end - r + 1)
                l += 1
            else:
                r += 1
    
    def merge(self, nums: List[int], start: int, mid: int, end: int):
        # Standard merge operation without affecting check_count
        merged = []
        l, r = start, mid + 1
        
        while l <= mid and r <= end:
            if nums[l] <= nums[r]:
                merged.append(nums[l])
                l += 1
            else:
                merged.append(nums[r])
                r += 1
        
        while l <= mid:
            merged.append(nums[l])
            l += 1
        while r <= end:
            merged.append(nums[r])
            r += 1
        
        # Copy the merged elements back into the original array nums
        for i in range(len(merged)):
            nums[start + i] = merged[i]
    
    def merge_sort_and_count(self, nums: List[int], start: int, end: int, d: int):
        '''
        이 함수가 call 되고 끝나는 시점에서는, start ~ end 범위는 이미 정렬된것임. 
        '''
        if start >= end:
            return
        
        mid = (start + end) // 2
        self.merge_sort_and_count(nums, start, mid, d)
        self.merge_sort_and_count(nums, mid + 1, end, d)
        self.check_count(nums, start, mid, end, d)  # Count without sorting
        self.merge(nums, start, mid, end)  # Sort the array after counting
    
    def numberOfPairs(self, nums1: List[int], nums2: List[int], diff: int) -> int:
        n = len(nums1)
        C = [nums1[i] - nums2[i] for i in range(n)]
        
        self.merge_sort_and_count(C, 0, n - 1, diff)
        return self.count


class Solution:
    def numberOfPairs(self, nums1: List[int], nums2: List[int], diff: int) -> int:
        C = [nums1[i] - nums2[i] for i in range(len(nums1))]
        self.count = 0
        self.merge_sort_and_count(C, 0, len(C)-1, diff)
        return self.count

    def merge_sort_and_count(self, nums, start, end, diff):
        '''
        이 함수가 call 되고 끝나는 시점에서는, start ~ end 범위는 이미 정렬된것임. 
        '''
        if start >= end:
            return 
        mid = (start + end) // 2
        self.merge_sort_and_count(nums, start, mid, diff)
        self.merge_sort_and_count(nums, mid+1, end, diff)
        self.check_count(nums, start, mid, end, diff) # 주어진 수식을 만족하는것이 몇개나 있는지 카운팅
        self.merge(nums, start, mid, end) # perform sorting

    def check_count(self, nums, start, mid, end, diff):
        p1, p2 = start, mid+1
        while p1 <= mid and p2 <= end:
            if nums[p1] <= nums[p2] + diff:
                self.count += (end - p2 + 1)
                p1 += 1
            else:
                p2 += 1
    
    def merge(self, nums, start, mid, end):
        merged = []
        p1, p2 = start, mid+1
        while p1 <= mid and p2 <= end:
            if nums[p1] <= nums[p2]:
                merged.append(nums[p1])
                p1 += 1
            else:
                merged.append(nums[p2])
                p2 += 1
        
        while p1 <= mid:
            merged.append(nums[p1])
            p1 += 1
        
        while p2 <= end:
            merged.append(nums[p2])
            p2 += 1
        
        nums[start:end+1]=merged


















class SegmentTree:
    def __init__(self, size):
        self.size = size
        self.tree = [0] * (2 * size)

    def update(self, idx):
        # Ensure idx is within the bounds
        if idx < 0 or idx >= self.size:
            return
        idx += self.size  # Shift to the leaf position
        while idx > 0:
            self.tree[idx] += 1
            idx //= 2

    def query(self, left, right):
        # Ensure left and right are within bounds
        if left < 0:
            left = 0
        if right >= self.size:
            right = self.size - 1
        left += self.size  # Shift to the leaf position
        right += self.size
        sum = 0
        while left <= right:
            if left % 2 == 1:  # If left is a right child
                sum += self.tree[left]
                left += 1
            if right % 2 == 0:  # If right is a left child
                sum += self.tree[right]
                right -= 1
            left //= 2
            right //= 2
        return sum

class Solution:
    def numberOfPairs(self, nums1, nums2, diff):
        SHIFT = 30000
        n = len(nums1)
        seg_tree = SegmentTree(SHIFT * 2 + 1)  # Extra space to accommodate the SHIFT
        res = 0

        for i in range(n):
            ndiff = nums1[i] - nums2[i]
            if ndiff + diff + SHIFT >= 0 and ndiff + SHIFT >= 0:
                res += seg_tree.query(0, ndiff + diff + SHIFT)
            seg_tree.update(ndiff + SHIFT)

        return res


























class Solution:
    def numberOfPairs(self, nums1: List[int], nums2: List[int], diff: int) -> int:
        c = [nums1[i] - nums2[i] for i in range(len(nums1))]
        sl = SortedList()
        cnt = 0
        for i in range(len(c)):
            idx = sl.bisect_right(c[i] + diff)
            cnt += idx-1 - 0 + 1
            sl.add(c[i])
        return cnt



class Solution:
    def numberOfPairs(self, nums1: List[int], nums2: List[int], diff: int) -> int:
        self.diff = diff
        c = [nums1[i] - nums2[i] for i in range(len(nums1))]
        self.cnt = 0
        self.merge_sort_and_count(c, 0, len(c)-1)
        return self.cnt

    def merge_sort_and_count(self, nums, p1, p2):
        if p1 >= p2:
            return
        pm = (p1 + p2)//2
        self.merge_sort_and_count(nums, p1, pm)
        self.merge_sort_and_count(nums, pm+1, p2)
        self.count(nums, p1, pm, p2)

        l1 = p1
        l2 = pm + 1
        merged = []
        while l1 <= pm and l2 <= p2:
            if nums[l1] <= nums[l2]:
                merged.append(nums[l1])
                l1 += 1
            else:
                merged.append(nums[l2])
                l2 += 1
        while l1 <= pm:
            merged.append(nums[l1])
            l1 += 1
        while l2 <= p2:
            merged.append(nums[l2])
            l2 += 1
        nums[p1:p2+1] = merged

    def count(self, nums, p1, pm, p2):
        l1 = p1
        l2 = pm+1
        while l1 <= pm and l2 <= p2:
            if nums[l1] <= nums[l2] + self.diff:
                self.cnt += p2 - l2 + 1
                l1 += 1
            else:
                l2 += 1





















from sortedcontainers import SortedList

class Solution:
    def numberOfPairs(self, nums1: List[int], nums2: List[int], diff: int) -> int:
        # c[i] <= c[j] + diff
        c = [nums1[i] - nums2[i] for i in range(len(nums1))]
        sl = SortedList()
        ans = 0
        for i in range(len(c)):
            idx = sl.bisect_right(c[i] + diff)
            ans += idx
            sl.add(c[i])
        return ans


class Solution:
    def numberOfPairs(self, nums1: List[int], nums2: List[int], diff: int) -> int:
        self.cnt = 0
        self.c = [nums1[i] - nums2[i] for i in range(len(nums1))]
        self.diff = diff
        self.sort_and_count(0, len(nums1)-1)
        
        return self.cnt
    
    def sort_and_count(self, p1, p2):
        if p1 >= p2:
            return 
        
        pm = (p1 + p2) // 2
        self.sort_and_count(p1, pm)
        self.sort_and_count(pm+1, p2)
        self.count(p1, pm, p2)

        l1 = p1
        l2 = pm+1
        merged = []
        while l1 <= pm and l2 <= p2:
            if self.c[l1] <= self.c[l2]:
                merged.append(self.c[l1])
                l1 += 1
            else:
                merged.append(self.c[l2])
                l2 += 1

        while l1 <= pm:
            merged.append(self.c[l1])
            l1 += 1
        while l2 <= p2:
            merged.append(self.c[l2])
            l2 += 1
        self.c[p1:p2+1] = merged

    def count(self, p1, pm, p2):
        l1 = p1
        l2 = pm + 1
        while l1 <= pm and l2 <= p2:
            if self.c[l1] <= self.c[l2] + self.diff:
                self.cnt += (p2 - l2 + 1)
                l1 += 1
            else:
                l2 += 1
        























class Solution:
    def numberOfPairs(self, nums1: List[int], nums2: List[int], diff: int) -> int:
        self.c = [nums1[i] - nums2[i] for i in range(len(nums1))]
        # c[i] <= c[j] + diff
        self.diff = diff
        self.cnt = 0
        self.merge_sort_and_count(0, len(self.c)-1)
        return self.cnt

    def merge_sort_and_count(self, p1, p2):
        if p1 >= p2:
            return
        pm = (p1 + p2) // 2
        self.merge_sort_and_count(p1, pm)
        self.merge_sort_and_count(pm+1, p2)
        self.count(p1, pm, p2)

        l1 = p1
        l2 = pm+1
        merged = []
        while l1 <= pm and l2 <= p2:
            if self.c[l1] <= self.c[l2]:
                merged.append(self.c[l1])
                l1 += 1
            else:
                merged.append(self.c[l2])
                l2 += 1
        while l1 <= pm:
            merged.append(self.c[l1])
            l1 += 1
        while l2 <= p2:
            merged.append(self.c[l2])
            l2 += 1
        self.c[p1:p2+1] = merged

    def count(self, p1, pm, p2):
        # c[i] <= c[j] + diff
        l2 = pm+1
        for l1 in range(p1, pm+1):
            while l2 <= p2 and self.c[l1] > self.c[l2] + self.diff:
                l2 += 1
            self.cnt += (p2-1 - (l2-1) + 1)
            #self.cnt += (l2 - (pm + 1))
















class Solution:
    def numberOfPairs(self, nums1: List[int], nums2: List[int], diff: int) -> int:
        # nums1[i] - nums2[i] <= nums1[j] - nums2[i] + diff
        self.diff = diff
        self.nums = [nums1[i] - nums2[i] for i in range(len(nums1))]
        # c[i] <= c[j] + diff
        self.cnt = 0
        self.merge_sort_and_count(0, len(nums1)-1)
        return self.cnt

    def merge_sort_and_count(self, p1, p2):
        if p1 >= p2:
            return 
        pm = (p1 + p2) // 2
        self.merge_sort_and_count(p1, pm)
        self.merge_sort_and_count(pm+1, p2)
        self.count(p1, pm, p2)
        
        l1, l2 = p1, pm+1
        merged = []
        while l1 <= pm and l2 <= p2:
            if self.nums[l1] <= self.nums[l2]:
                merged.append(self.nums[l1])
                l1 += 1
            else:
                merged.append(self.nums[l2])
                l2 += 1
        while l1 <= pm:
            merged.append(self.nums[l1])
            l1 += 1
        while l2 <= p2:
            merged.append(self.nums[l2])
            l2 += 1
        self.nums[p1:p2+1] = merged
    
    def count(self, p1, pm, p2):
        # c[i] <= c[j] + diff
        i, j = p1, pm + 1
        while i <= pm:
            while j <= p2 and self.nums[i] > self.nums[j] + self.diff:
                j += 1
            self.cnt += (p2 - j + 1)
            i += 1
        






















class Solution:
    def numberOfPairs(self, nums1: List[int], nums2: List[int], diff: int) -> int:
        self.c = [nums1[i] - nums2[i] for i in range(len(nums1))]
        self.diff = diff
        self.cnt = 0
        self.merge_sort_and_count(0, len(self.c)-1)
        return self.cnt
    
    def merge_sort_and_count(self, p1, p2):
        if p1 >= p2:
            return 
        pm = (p1 + p2) // 2
        self.merge_sort_and_count(p1, pm)
        self.merge_sort_and_count(pm+1, p2)
        self.count(p1, pm, p2)

        l1, l2 = p1, pm + 1
        merged = []
        while l1 <= pm and l2 <= p2:
            if self.c[l1] < self.c[l2]:
                merged.append(self.c[l1])
                l1 += 1
            else:
                merged.append(self.c[l2])
                l2 += 1
        while l1 <= pm:
            merged.append(self.c[l1])
            l1 += 1
        while l2 <= p2:
            merged.append(self.c[l2])
            l2 += 1
        self.c[p1:p2+1] = merged
    
    def count(self, p1, pm, p2):
        # c[i] <= c[j] + self.diff
        l1, l2 = p1, pm + 1
        for l1 in range(p1, pm+1):
            while l2 <= p2 and self.c[l1] > self.c[l2] + self.diff:
                l2 += 1
            self.cnt += (p2 - l2 + 1)
        
36400