ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

题解 [SCOI2008]斜堆

2022-08-01 14:36:27  阅读:129  来源: 互联网

标签:ch 题解 儿子 斜堆 满足 SCOI2008 100 节点 性质


好题。一道很有趣的性质提。

因为自己搞错结论然后改了 1h(悲

闲话少说,切入正题——


这是不断插入的,所以根据套路我们会考虑最后一个插入的节点的性质。显然满足:

  1. 它是从根不停往左走的路上。
  2. 它没有右子树。

但是这样的点有很多,我们来深入分析。性质 1 说明这些点在一条链上,我们知道插入的时候会将当前节点的左右儿子变换。我们要由此引出第三条性质:一个节点不可能只有右儿子。这是显而易见的。根据性质三,我们可以知道,假设我们有 \(a, b\) 满足性质 1 与性质 2,\(a\) 深度比 \(b\) 大,则会交换 \(b\) 的左右儿子,\(b\) 只有右儿子,与第三条性质相悖。

那么我们就可以知道了,最后一个插入的节点必然是深度最小的满足性质 1,2 的节点。

但是也有例外,假设我们这样一棵条链:0-1为什么画图都要偷懒!正确答案应该是 1 0,但是如果按照上面的算法就是 0 1

我们会发现删除 1 反转它的祖先依旧可以保证所有节点满足性质 3。这是因为首先它的父亲是 0 本身满足性质 1 与性质 2 没有右子树,其次 1 是叶子节点,没有子树,因此不需要给 0 新增儿子。

我们能得到另外一个性质,令当前满足性质 1 性质 2 的最浅节点为 \(d\),若 \(d\) 的左儿子是叶子节点,就选择删除 \(d\) 的左儿子,否则删除 \(d\)。

删除以后把自己的子树给父亲,反转祖宗的左右儿子。

//SIXIANG
#include <iostream> 
#include <vector>
#define MAXN 100000
#define QWQ cout << "QWQ" << endl;
using namespace std;
int ch[MAXN + 10][3], a[MAXN + 10], rt;
//0 左儿子 1 右儿子 2 父亲 
int Find() {
	int now = rt;
	while(1) {
		if(ch[now][1] == -1) return now;
		now = ch[now][0];
	}
} 
bool isleaf(int x) {
	return ((ch[x][0] == ch[x][1]) && (ch[x][0] == -1));
}
int Delete() {
	int d = Find();
	if(d != -1 && isleaf(ch[d][0])) d = ch[d][0];
	if(d == rt)
		rt = ch[d][0];
	else {
		ch[ch[d][2]][0] = ch[d][0];
		if(ch[d][0] != -1) ch[ch[d][0]][2] = ch[d][2];
		int to = ch[d][2];
		while(to != -1) {
			swap(ch[to][0], ch[to][1]);
			to = ch[to][2];
		}
	}
	return d;
}
int main() {
	int n; cin >> n;
	for(int p = 0; p <= n; p++) ch[p][0] = ch[p][1] = ch[p][2] = -1;
	for(int p = 1; p <= n; p++) {
		cin >> a[p];
		if(a[p] >= 100) ch[a[p] - 100][1] = p, ch[p][2] = a[p] - 100;
		else ch[a[p]][0] = p, ch[p][2] = a[p];
	}
	for(int p = 0; p <= n; p++)
		a[n - p] = Delete();
	for(int p = 0; p <= n; p++)
		cout << a[p] << ' ';
}

标签:ch,题解,儿子,斜堆,满足,SCOI2008,100,节点,性质
来源: https://www.cnblogs.com/thirty-two/p/16540134.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有