1 条题解

  • 0
    @ 2025-12-10 13:40:49

    题解:POI 2011 Tree Rotations

    问题本质

    给一棵二叉树,每个叶子有唯一编号(1~n)。可以交换任意内部节点的左右子树(旋转),目标是让中序遍历叶子序列的逆序对最少。

    核心思路

    对每个节点,左右子树内部的最优逆序对数可以递归求出。

    节点处的选择只影响跨左右子树的逆序对,与左右子树内部顺序无关。

    跨子树逆序对数量可以通过合并左右子树的权值线段树时计算得出。

    关键结论

    设节点 u 的左右子树叶子值集合为 L 和 R,大小分别为 a 和 b:

    不旋转时跨子树逆序对 cross = ∑{x∈L} ∑{y∈R} [x > y]

    旋转时跨子树逆序对 cross_rev = ∑{x∈L} ∑{y∈R} [x < y]

    因为 cross + cross_rev = a*b,所以只需计算其中一个。

    算法流程

    递归处理:DFS 遍历树的输入格式

    线段树合并:每个节点维护其子树叶子值的权值线段树(值域 1~n)

    合并时计算:

    合并左右子树的线段树时,同时计算 cross

    cross = 左子树中大于右子树当前值的元素个数,在合并过程中累加

    决策:

    节点 u 的逆序对数 = inv_left + inv_right + min(cross, a*b - cross)

    选择 cross 或 cross_rev 中较小的作为跨子树逆序对 时间复杂度 线段树合并总复杂度 O(n log n)

    空间复杂度 O(n log n)

    • 1

    信息

    ID
    4381
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    4
    已通过
    1
    上传者