Dances (Hard Version) (Codeforces 1887A2)
Tags: Greedy, binary search

This is the hard version of the problem. The only difference is that in this version $$$m \leq 10^9$$$.You are given two arrays of integers $$$a_1, a_2, \ldots, a_n$$$ and $$$b_1, b_2, \ldots, b_n$$$. Before applying any operations, you can reorder the elements of each array as you wish. Then, in one operation, you will perform both of the following actions, if the arrays are not empty: Choose any element from array $$$a$$$ and remove it (all remaining elements are shifted to a new array $$$a$$$), Choose any element from array $$$b$$$ and remove it (all remaining elements are shifted to a new array $$$b$$$).Let $$$k$$$ be the final size of both arrays. You need to find the minimum number of operations required to satisfy $$$a_i < b_i$$$ for all $$$1 \leq i \leq k$$$.This problem was too easy, so the problem author decided to make it more challenging. You are also given a positive integer $$$m$$$. Now, you need to find the sum of answers to the problem for $$$m$$$ pairs of arrays $$$(c[i], b)$$$, where $$$1 \leq i \leq m$$$. Array $$$c[i]$$$ is obtained from $$$a$$$ as follows: $$$c[i]_1 = i$$$, $$$c[i]_j = a_j$$$, for $$$2 \leq j \leq n$$$.

Input: Each test consists of multiple test cases. The first line contains a single integer $$$t$$$ ($$$1 \leq t \leq 10^4$$$) - the number of sets of input data. This is followed by their description.The first line of each test case contains two integers $$$n$$$ and $$$m$$$ ($$$2 \leq n \leq 10^5$$$, $$$1 \leq m \leq 10^9$$$) - the size of arrays $$$a$$$ and $$$b$$$ and the constraints on the value of element $$$a_1$$$.The second line of each test case contains $$$n - 1$$$ integers $$$a_2, \ldots, a_n$$$ ($$$1 \leq a_i \leq 10^9$$$).The third line of each test case contains $$$n$$$ integers $$$b_1, b_2, \ldots, b_n$$$ ($$$1 \leq b_i \leq 10^9$$$).It is guaranteed that the sum of $$$n$$$ over all test cases does not exceed $$$10^5$$$.

Output: For each test case, output the total number of minimum operations for all pairs of arrays $$$(c_i, b)$$$.

Note: In the first test case: For the pair of arrays $$$([1, 1], [3, 2])$$$, the answer is $$$0$$$. No operations or reordering of elements are needed. For the pair of arrays $$$([2, 1], [3, 2])$$$, the answer is $$$0$$$. The elements of the first array can be rearranged to obtain $$$[1, 2)$$$. No operations are needed. For the pair of arrays $$$([3, 1], [3, 2])$$$, the answer is $$$1$$$. The element $$$3$$$ can be removed from the first array and the element $$$2$$$ can be removed from the second array. For the pair of arrays $$$([4, 1], [3, 2])$$$, the answer is $$$1$$$. The element $$$4$$$ can be removed from the first array and the element $$$3$$$ can be removed from the second array.

Sample Inputs:
4
2 4
1
3 2
4 7
5 1 5
3 8 3 3
8 4
4 3 3 2 2 1 1
1 1 1 1 3 3 3 3
9 1
9 2 8 3 7 4 6 5
1 2 3 2 1 4 5 6 5

Sample Outputs:
2
12
16
4

Solution (Python):
def solve(nums1, nums2):
    result = 0
    nums1.sort()
    nums2.sort()
    n1 = len(nums1)
    n2 = len(nums2)
    dp1 = [0 for i in range(n2)]
    pos1 = 0
    for i in range(n2):
        if pos1 < n1 and nums2[i] > nums1[pos1]:
            dp1[i] = 1
            pos1 += 1
    remain = n2 - pos1
    lastMax = nums2[n2 - 1]
    for i in range(n2 - 1, -1, -1):
        if dp1[i] == 0:
            lastMax = nums2[i]
            break
    return (remain, lastMax)
T = int(input())
final = []
for t in range(T):
    t1 = input().split(' ')
    (_, m) = (t1[0], int(t1[1]))
    a = input().split(' ')
    a = [int(e) for e in a]
    b = input().split(' ')
    b = [int(e) for e in b]
    sum = 0
    maxb = max(b)
    currSum = sum
    (currSum, lastMax) = solve(a, b)
    if lastMax > m:
        sum = (currSum - 1) * m
        print(f'{sum}')
    else:
        sum = (currSum - 1) * (lastMax - 1) + currSum * (m - lastMax + 1)
        print(f'{sum}')

Solution (Python):
from sys import stdin, stdout
(input, print) = (stdin.readline, stdout.write)
t = int(input())
for _ in range(t):
    (n, m) = list(map(int, input().split()))
    a = sorted(list(map(int, input().split())))
    b = sorted(list(map(int, input().split())))
    (ans, rem, i, j) = (0, 1, 0, 0)
    while i < n - 1 and j < n:
        if a[i] < b[j]:
            i += 1
            ans += 1
        else:
            rem = max(rem, b[j])
        j += 1
    if j < n:
        rem = b[-1]
    res = (n - ans) * m - min(rem - 1, m)
    print(str(res) + '\n')

Solution (Python):
import sys, os, io
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline

def binary_search(c1, c2):
    m = (c1 + c2 + 1) // 2
    while abs(c1 - c2) > 1:
        m = (c1 + c2 + 1) // 2
        if ok(m):
            c2 = m
        else:
            c1 = m
    m = max(m - 1, 0)
    while not ok(m):
        m += 1
    return m

def ok(m):
    if m >= n:
        return True
    for i in range(n - m):
        if not a[i] < b[i + m]:
            return False
    return True
t = int(input())
ans = []
inf = pow(10, 9) + 1
for _ in range(t):
    (n, m) = map(int, input().split())
    a = [1] + list(map(int, input().split()))
    b = list(map(int, input().split()))
    a.sort()
    b.sort()
    now = binary_search(0, n + 1)
    a.append(inf)
    b.append(inf)
    ans0 = 0
    l = 1
    for i in range(n):
        r = min(a[i + 1], m + 1)
        while i + now < n and l < r:
            c = min(b[i + now], r)
            ans0 += (c - l) * now
            l = c
            if l ^ r:
                now += 1
        if i + now >= n:
            ans0 += (m - l + 1) * now
            break
        if r == m + 1:
            break
        a[i] = a[i + 1]
        while i + now < n and (not a[i] < b[i + now]):
            now += 1
    ans.append(ans0)
sys.stdout.write('\n'.join(map(str, ans)))