from typing import List


def roc_value(lst1: List[float], lst2: List[float]) -> float:
    """
    :param lst1: a list of numbers
    :param lst2: another list of numbers
    :return: the proportion of pairs (x, y), where x is from lst1 and y is from lst2, for which
    x < y, with x == y counting as half an instance.
    """
    if len(lst1) == 0 or len(lst2) == 0:
        return 0.5
    pairs = sorted([(x, 1) for x in lst1] + [(x, 2) for x in lst2])
    # Number of items from lst1 seen so far
    n1 = 0
    # Number of pairs (x, y) seen so far where x is from lst1, y is from lst2, and x < y; if x == y
    # we count 0.5
    numerator = 0.0
    # The last value seen in lst1; initialized to a non-number to force non-equality
    last_value = None
    # Number of items seen in lst1 that are equal to last_value
    last_value_count = 0
    for value, idx in pairs:
        if idx == 1:
            # It's an item from lst1.
            n1 += 1
            # Update last_value and its count.
            if value == last_value:
                last_value_count += 1
            else:
                last_value = value
                last_value_count = 1
        else:
            # It's an item from lst2.
            if value != last_value:
                last_value_count = 0
            # We add on 1 for each of the n1 members of lst1 previously seen, except we only
            # add on 0.5 for last_value_count of them.
            numerator += n1 - last_value_count * 0.5
    # Number of pairs (x, y) in the data where x is from lst1 and y is from lst2, regardless of order,
    # so that returned value is normalized to [0, 1].
    denominator = len(lst1) * len(lst2)
    return numerator / denominator