「Loj #2163」「Poi2011」Tree Rotations

Posted -wallace-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「Loj #2163」「Poi2011」Tree Rotations相关的知识,希望对你有一定的参考价值。

Description

现在有一棵二叉树,所有非叶子节点都有两个孩子。在每个叶子节点上有一个权值(有 (n) 个叶子节点,满足这些权值为 (1cdots n) 的一个排列)。

可以任意交换每个非叶子节点的左右孩子。

要求进行一系列交换,使得最终所有叶子节点的权值按照遍历序写出来,逆序对个数最少。

Hint

(1le nle 2 imes 10^5)

Solution

可以发现,对于其中一颗子树,不论如何变换都不会改变 这一颗子树中的结点与其他位置的结点组合产生的逆序对的个数 即这颗子树的变换不会改变上层之间的逆序对,所以只要考虑这颗子树中的就行了。

首先对所有结点开一个权值线段树,之后逐层合并即可。现在的问题就是,左右子树如何放置(是否交换)产生的逆序对最小。

我们可以在线段树合并的时候干这个事情。具体地,就是说当合并到结点 (a) (左子树结点) (, b)(右子树结点) 时,记 不交换产生的逆序对为 (u) ,交换的为 (v),那么:

  • (u) 加上 (a) 的右子树的大小 ( imes b) 左子树的大小
  • (v) 加上 (a) 的左子树的大小 ( imes b) 右子树的大小

一次合并完之后,( ext{ans} leftarrow ext{ans} + min(u, v)) 即可。

注意,实际节点数可能有 (n imes 2) 这么多,应开大空间。

Code

#include <iostream>
using namespace std;

const int N = 4e5 + 5;
const int S = N << 6;

int lc[S], rc[S], total = 0;
long long sum[S];
#define mid ((l + r) >> 1)
void increase(int &rt, int l, int r, int p) {
	if (!rt) rt = ++total;
	sum[rt]++;
	if (l == r) return;
	if (p <= mid) increase(lc[rt], l, mid, p);
	else increase(rc[rt], mid + 1, r, p);
}
int merge(int a, int b, int l, int r, long long& u, long long& v) {
	if (!a || !b) return a | b;
	if (l == r) return sum[a] += sum[b], a;
	u += sum[rc[a]] * sum[lc[b]];
	v += sum[lc[a]] * sum[rc[b]];
	lc[a] = merge(lc[a], lc[b], l, mid, u, v);
	rc[a] = merge(rc[a], rc[b], mid + 1, r, u, v);
	return sum[a] = sum[lc[a]] + sum[rc[a]], a;
}
#undef mid

int n;
long long ans = 0ll;
int solve() {
	int rt = 0, cur;
	cin >> cur;
	if (!cur) {
		int l = solve(), r = solve();
		long long u = 0ll, v = 0ll;
		rt = merge(l, r, 1, n, u, v);
		ans += min(u, v);
	} else increase(rt, 1, n, cur);
	return rt;
}

signed main() {
	cin >> n;
	solve();
	cout << ans << endl;
	return 0;
}

以上是关于「Loj #2163」「Poi2011」Tree Rotations的主要内容,如果未能解决你的问题,请参考以下文章

POI2011 Tree Rotations

[BZOJ2212][POI2011]Tree Rotations(线段树合并)

BZOJ_2212_[Poi2011]Tree Rotations_线段树合并

bzoj2212 [Poi2011]Tree Rotations 线段树合并

bzoj 2212[POI2011]ROT-Tree Rotations - 线段树合并

BZOJ 2212 [Poi2011]Tree Rotations