<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>线段树合并 on Zirnc's Blog</title><link>https://blog.chungzh.cn/blog/%E7%BA%BF%E6%AE%B5%E6%A0%91%E5%90%88%E5%B9%B6/</link><description>Recent content in 线段树合并 on Zirnc's Blog</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Sun, 14 Aug 2022 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.chungzh.cn/blog/%E7%BA%BF%E6%AE%B5%E6%A0%91%E5%90%88%E5%B9%B6/index.xml" rel="self" type="application/rss+xml"/><item><title>Luogu-P3521 「POI2011」ROT-Tree Rotations</title><link>https://blog.chungzh.cn/oi-history/luogu-p3521/</link><pubDate>Sun, 14 Aug 2022 00:00:00 +0000</pubDate><guid>https://blog.chungzh.cn/oi-history/luogu-p3521/</guid><description>题意 给定一颗有 $n$ 个叶节点的二叉树。每个叶节点都有一个权值 $p_i$（注意，根不是叶节点），所有叶节点的权值构成了一个 $1 \sim n$ 的排列。
对于这棵二叉树的任何一个结点，保证其要么是叶节点，要么左右两个孩子都存在。
现在你可以任选一些节点，交换这些节点的左右子树。
在最终的树上，按照先序遍历遍历整棵树并依次写下遇到的叶结点的权值构成一个长度为 $n$ 的排列，你需要最小化这个排列的逆序对数。
$2 \leq n \leq 2 \times 10^5$， $0 \leq x \leq n$，所有叶节点的权值是一个 $1 \sim n$ 的排列。
分析 按照先序遍历整棵树，取叶结点，用人话说就是从左到右取叶子结点。
重要性质：交换了一个点的左右子树之后，不会影响左子树内和右子树内的逆序对数量。
考虑一个任意的结点，对它的子树中叶子的逆序对进行分类讨论：
都在左子树内； 都在右子树内； 跨越左右子树。 交换左右子树之后，受到影响的显然只有第三种情况。第一、第二种情况分治下去就可以转化成第三种再计算。
如何计算答案呢？一开始，对于每一个叶子结点，我们都建立一棵权值线段树（动态开点）并记录 $p_i$ 出现了 $1$ 次。合并 $r1, r2$ 时，逆序对的个数就是 $tree[rc[r1]] \times tree[lc[r2]]$。因为 $r1, r2$ 对应的权值区间 $[L, R]$ 是相同的，而 $lc[r1], lc[r2]$ 对应的权值区间就是 $[L, M]$， $rc[r1], rc[r2]$ 对应的权值区间是 $[M+1, R]$，$rc[]$ 中记录的数都比 $lc[]$ 中的要大，而 $r1$ 对应的数的编号小于 $r2$（也就是 $r1$ 是左子树，$r2$ 是右子树），满足逆序对的条件。</description></item><item><title>线段树合并笔记</title><link>https://blog.chungzh.cn/oi-history/merge-seg-tree/</link><pubDate>Sun, 14 Aug 2022 00:00:00 +0000</pubDate><guid>https://blog.chungzh.cn/oi-history/merge-seg-tree/</guid><description>前置知识：动态开点线段树。
二叉树合并 合并是一个递归的过程。首先合并两棵以 $u, v$ 为根的二叉树：
考虑左子树 如果 $u, v$ 都没有左子树，那么直接留空； 如果只有 $u$ 有左子树，那么 $u$ 的左子树保留不动； 如果只有 $v$ 有左子树，那么将 $v$ 的左子树接过来，成为 $u$ 的左子树； 如果 $u, v$ 均有左子树，那么递归合并 $u, v$ 的左子树，结果赋给 $u$ 的左子树。 考虑右子树 如果 $u, v$ 都没有右子树，那么直接留空； 如果只有 $u$ 有右子树，那么 $u$ 的右子树保留不动； 如果只有 $v$ 有右子树，那么将 $v$ 的右子树接过来，成为 $u$ 的右子树； 如果 $u, v$ 均有右子树，那么递归合并 $u, v$ 的右子树，结果赋给 $u$ 的右子树。 最后我们就将两棵二叉树合并成了一个以 $u$ 为根的二叉树。
复杂度分析：在上面的过程中，仅当 $u, v$ 均有左（右）孩子时才会进行递归，访问这个左（右）孩子。时间复杂度就是两棵二叉树中重复的结点的数量。</description></item></channel></rss>