You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求满足特定条件的pair<int,int>数对对数(需优于O(N²)复杂度)

Alright, let's break down how to solve this problem efficiently—way better than the naive O(n²) approach.

First off, let's simplify the problem. The goal is to count pairs of (a_i, b_i) and (a_j, b_j) where |a_i - a_j| ≤ min(b_i, b_j).

Step 1: Simplify the Condition with Sorting

If we sort all pairs by their a value in ascending order, then for any i < j, we know a_j ≥ a_i. This lets us drop the absolute value: the condition becomes a_j - a_i ≤ min(b_i, b_j).

We can rephrase the invalid pairs (which are easier to count) to avoid double-counting:

  1. Invalid case 1: b_i ≤ b_j but a_j > a_i + b_i (the difference exceeds the smaller b value)
  2. Invalid case 2: b_i > b_j but a_i < a_j - b_j (again, the difference exceeds the smaller b value)

Our valid pair count will be the total number of possible pairs minus the count of these two invalid cases.

Step 2: Efficiently Count Invalid Pairs with Fenwick Trees

To count these invalid cases in O(n log n) time, we'll use Fenwick Trees (Binary Indexed Trees) combined with offline processing and value discretization (since values can be large).

First, Implement a Fenwick Tree

This data structure supports fast point updates and prefix sum queries:

class FenwickTree:
    def __init__(self, size):
        self.n = size
        self.tree = [0] * (self.n + 1)
    
    def update(self, idx, delta=1):
        while idx <= self.n:
            self.tree[idx] += delta
            idx += idx & -idx
    
    def query(self, idx):
        res = 0
        while idx > 0:
            res += self.tree[idx]
            idx -= idx & -idx
        return res

Discretization Helper

Since Fenwick Trees work best with small integer indices, we'll map large values to a compressed range:

def discretize(values):
    sorted_unique = sorted(list(set(values)))
    return {x: i + 1 for i, x in enumerate(sorted_unique)}, len(sorted_unique)

Count Invalid Case 1

Count pairs where i < j, b_i ≤ b_j, and a_j > a_i + b_i:

def calculate_count1(pairs):
    n = len(pairs)
    events = []
    for i in range(n):
        a, b = pairs[i]
        R = a + b
        events.append((b, 0, a, R))  # Insert event (type 0)
        events.append((b, 1, a, a))  # Query event (type 1)
    
    # Sort: by b ascending, insert before query, then by a ascending
    events.sort(key=lambda x: (x[0], x[1], x[2]))
    
    # Discretize all relevant values
    values = [val for _, _, _, val in events]
    val_to_idx, size = discretize(values)
    ft = FenwickTree(size)
    
    count1 = 0
    for b, typ, a, val in events:
        if typ == 0:
            idx = val_to_idx[val]
            ft.update(idx)
        else:
            # Query number of values < val
            idx = val_to_idx.get(val, size + 1) - 1
            count1 += ft.query(idx) if idx > 0 else 0
    return count1

Count Invalid Case 2

Count pairs where i < j, b_i > b_j, and a_i < a_j - b_j:

def calculate_count2(pairs):
    n = len(pairs)
    events = []
    for i in range(n):
        a, b = pairs[i]
        L = a - b
        events.append((b, 0, a, a))  # Insert event (type 0)
        events.append((b, 1, a, L))  # Query event (type 1)
    
    # Sort: by b descending, query before insert, then by a ascending
    events.sort(key=lambda x: (-x[0], x[1], x[2]))
    
    # Discretize all relevant values
    values = [val for _, _, _, val in events]
    val_to_idx, size = discretize(values)
    ft = FenwickTree(size)
    
    count2 = 0
    for b, typ, a, val in events:
        if typ == 1:
            # Query number of values < val
            idx = val_to_idx.get(val, size + 1) - 1
            count2 += ft.query(idx) if idx > 0 else 0
        else:
            idx = val_to_idx[val]
            ft.update(idx)
    return count2

Step 3: Calculate Final Valid Pair Count

Put it all together by subtracting invalid pairs from the total possible pairs:

def count_valid_pairs(pairs):
    sorted_pairs = sorted(pairs, key=lambda x: x[0])
    n = len(sorted_pairs)
    if n < 2:
        return 0
    total_pairs = n * (n - 1) // 2
    invalid1 = calculate_count1(sorted_pairs)
    invalid2 = calculate_count2(sorted_pairs)
    return total_pairs - invalid1 - invalid2

Test the Solution

Let's verify with your example:

# Test case: pairs = [(2,5), (7,4)]
print(count_valid_pairs([(2,5), (7,4)]))  # Output: 1 (correct)

Time Complexity

  • Sorting pairs: O(n log n)
  • Processing each invalid case: O(n log n) (event sorting + Fenwick Tree operations)
  • Total time: O(n log n), which is a massive improvement over O(n²) for large n.

内容的提问来源于stack exchange,提问作者yobro97

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:58:02