蓝桥20102, 二维偏序:线段树


本题不知道他符号用的是哪个体系里的,最后靠猜的,就是 j 在 i 的右上方(可以重叠)
按照x排序后,遍历所有点,看已遍历的点中有多少在查询点的左下方。思路是用线段树记录y的区间中有多少个点
操作涉及到按x排序,离散化y

import os
import sys

# 请在此输入您的代码
from collections import defaultdict
# 使用线段树,query(x,y)内容就是查询已遍历的纵坐标小于等于y的节点数量
class Seg:
    def __init__(self, n):
        self.n = n
        self.t = [0] * 4 * n
    
    def up(self, a, b):
        return a + b
    
    def do(self, o):
        self.t[o] += 1

    def update(self, a, b, o = 1, l = 0, r = None):
        if r is None: r = self.n - 1
        if a <= l and b >= r:
            self.do(o)
            return
        m = (l + r) // 2
        if a <= m:
            self.update(a, b, o * 2, l, m)
        if b > m:
            self.update(a, b, o * 2 + 1, m + 1, r)
        self.t[o] = self.up(self.t[o * 2], self.t[o * 2 + 1])
    
    def query(self, a, b, o = 1, l = 0, r = None):
        if r is None: r = self.n - 1
        if a <= l and b >= r:
            return self.t[o]
        m = (l + r) // 2
        res = self.t[0]
        if a <= m:
            res = self.up(res, self.query(a, b, o * 2, l, m))
        if b > m:
            res = self.up(res, self.query(a, b, o * 2 + 1, m + 1, r))
        return res

n = int(input())
tuples = []
dic = defaultdict(int) # 查询y值对应的索引
for _ in range(n):
    x, y = map(int, input().split())
    tuples.append((x, y))
tuples.sort()
arr = list(set(y for x, y in tuples)) # 去重y之后,离散的y值就能对应连续的索引
arr.sort()
for i, x in enumerate(arr):
    dic[x] = i
length = len(arr)

tree = Seg(length)
ans = 0
for x, y in tuples:
    ans += tree.query(0, dic[y])
    tree.update(dic[y], dic[y])
print(ans)
 
posted @ 2025-03-11 15:56  凉叶染香  阅读(16)  评论(0)    收藏  举报