【bzoj1078】 SCOI2008—斜堆
http://www.lydsy.com/JudgeOnline/problem.php?id=1078 (题目链接)
题意
给出一个斜堆,并给出其插入的操作,求一个字典序最小的插入顺序。
Solution
YY了很久,画出样例,你会发现很神奇的性质:一般情况下,因为是一个一个插入节点的,左子树与右子树的大小要么相等要么左子树比右子树大1。
然而,我忽略了一条链的情况,写写画画搞来搞去,最后分类讨论了一下。关键的地方是要想到我们对于一棵子树,在前提条件相同的情况下,应尽肯能的早插入根,因为是个小根堆,所以根的字典序一定是最小的。
我们这样操作:对于节点x,它的左儿子l,右儿子r。dfs下去,分别得到l的子树的合并顺序和r的子树的合并顺序,再对x,l,r进行合并,跟归并排序有些类似吧。
对于节点x:
左子树大于右子树
1.左-右>=2
不停插左,直到左右子树大小相等
插根,先插左再插右
2.左-右=1
插根,先插左再插右
左子树等于右子树
插根,先插右再插左
左子树小于右子树
1.右-左>=2
不停插右,直到左-右=1
插根,先插左再插右
2.右-左=1
先插右2个
插根,先插左再插右
然后一路dfs递归合并就可以了
细节
节点标号从1开始会比较好
代码
// bzoj1078
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf 1<<30
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; const int maxn=100;
struct heap {int l,r;}tr[maxn];
int size[maxn],n;
vector<int> v[maxn]; void dfs(int x) {
size[x]=1;
if (tr[x].l) dfs(tr[x].l);
if (tr[x].r) dfs(tr[x].r);
size[x]+=size[tr[x].l]+size[tr[x].r];
}
void merge(int x) {
int l=tr[x].l,r=tr[x].r;
if (l) merge(l);
if (r) merge(r);
int ll=0,rr=0;
if (size[l]>size[r]) {
if (size[l]-size[r]>=2) {
for (;size[l]-size[r];ll++,size[l]--) v[x].push_back(v[l][ll]);
v[x].push_back(x);
while (size[l] || size[r]) {
if (size[l]==size[r]) v[x].push_back(v[r][rr++]),size[r]--;
else v[x].push_back(v[l][ll++]),size[l]--;
}
}
else {
v[x].push_back(x);
while (size[l] || size[r]) {
if (size[l]==size[r]) v[x].push_back(v[r][rr++]),size[r]--;
else v[x].push_back(v[l][ll++]),size[l]--;
}
}
}
else if (size[l]==size[r]) {
v[x].push_back(x);
while (size[l] || size[r]) {
if (size[l]==size[r]) v[x].push_back(v[r][rr++]),size[r]--;
else v[x].push_back(v[l][ll++]),size[l]--;
}
}
else if (size[l]<size[r]) {
if (size[r]-size[l]>=2) {
for (;size[l]-size[r]<1;rr++,size[r]--) v[x].push_back(v[r][rr]);
v[x].push_back(x);
while (size[l] || size[r]) {
if (size[l]==size[r]) v[x].push_back(v[r][rr++]),size[r]--;
else v[x].push_back(v[l][ll++]),size[l]--;
}
}
else {
v[x].push_back(v[r][rr++]),size[r]--;
v[x].push_back(v[r][rr++]),size[r]--;
v[x].push_back(x);
while (size[l] || size[r]) {
if (size[l]==size[r]) v[x].push_back(v[r][rr++]),size[r]--;
else v[x].push_back(v[l][ll++]),size[l]--;
}
}
}
}
int main() {
scanf("%d",&n);
for (int x,i=1;i<=n;i++) {
scanf("%d",&x);
if (x<100) tr[x+1].l=i+1;
else tr[x-99].r=i+1;
}
dfs(1);
merge(1);
for (int i=0;i<v[1].size();i++) printf("%d ",v[1][i]-1);
return 0;
}
【bzoj1078】 SCOI2008—斜堆的更多相关文章
- BZOJ1078 [SCOI2008]斜堆 堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1078 题意概括 斜堆(skew heap)是一种常用的数据结构.它也是二叉树,且满足与二叉堆相同的 ...
- [bzoj1078][SCOI2008][斜堆] (贪心)
Description 斜堆(skew heap)是一种常用的数据结构.它也是二叉树,且满足与二叉堆相同的堆性质:每个非根结点的值都比它父亲大.因此在整棵斜堆中,根的值最小.但斜堆不必是平衡的,每个结 ...
- BZOJ1078: [SCOI2008]斜堆
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1078 每一次进入的点一定是一个极左节点,然后将它所处在的整棵树左右翻转.加上一些情况的处理. ...
- 【BZOJ1078】[SCOI2008]斜堆(性质题)
[BZOJ1078][SCOI2008]斜堆(性质题) 题面 BZOJ 洛谷 题解 考虑一下这道题目的性质吧.思考一下最后插入进来的数是什么样子的.首先因为它是最后插入进来的,所以一定是比某个数小,然 ...
- 【bzoj1078】[SCOI2008]斜堆
2016-05-31 16:34:09 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1078 挖掘斜堆的性质233 http://www.cp ...
- BZOJ 1078: [SCOI2008]斜堆
1078: [SCOI2008]斜堆 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 770 Solved: 422[Submit][Status][ ...
- 【BZOJ 1078】 1078: [SCOI2008]斜堆
1078: [SCOI2008]斜堆 Description 斜堆(skew heap)是一种常用的数据结构.它也是二叉树,且满足与二叉堆相同的堆性质:每个非根结点的值都比它父亲大.因此在整棵斜堆中, ...
- [SCOI2008]斜堆
题目大意 1.题目描述 斜堆(skew heap)是一种常用的数据结构. 它也是二叉树,且满足与二叉堆相同的堆性质: 每个非根结点的值都比它父亲大.因此在整棵斜堆中,根的值最小. . 但斜堆不必是平衡 ...
- P2475 [SCOI2008]斜堆(递归模拟)
思路 可并堆真是一种神奇的东西 不得不说这道题是道好题,虽然并不需要可并堆,但是能加深对可并堆的理解 首先考虑斜堆的性质,斜堆和左偏树相似,有如下的性质 一个节点如果有右子树,就一定有左子树 最后插入 ...
随机推荐
- 《Redis设计与实现》阅读笔记(四)--字典
字典 字典,map,是用于保存键值对的抽象数据结构,是hash表实现.字典中的键唯一,通过键来操作值.Redis的数据库使用字典来作为底层实现. 定义 Redis的字典使用哈希表作为底层实现,一个哈希 ...
- C#如何在各类控件中输入\输出数据
文本框:TextBox Text - 按钮文字 TextBox.text=""; s=TextBox.text; 单选按钮+复选按钮 RadioButton,CheckBox Te ...
- Netty源码分析第3章(客户端接入流程)---->第2节: 处理接入事件之handle的创建
Netty源码分析第三章: 客户端接入流程 第二节: 处理接入事件之handle的创建 上一小节我们剖析完成了与channel绑定的ChannelConfig初始化相关的流程, 这一小节继续剖析客户端 ...
- Markdown 版本演进
本文作为 Markdown 系列的第二篇,对上一篇使用 Markdown 写技术博客,我踩过的 6个坑博客提到的版本变迁进行简要的提纲说明. 如果不想读文章,请直接看思维导图,使用 Atom + ma ...
- dom学习要点
Dom操作 1.文本内容操作 - innerText:操作文本 - innerHtml:操作全内容 //innerText标签: <div id='i2' ><a>土味程序员& ...
- gcc 与 g++的区分较
一:gcc与g++比较 误区一:gcc只能编译c代码,g++只能编译c++代码两者都可以,但是请注意:1.后缀为.c的,gcc把它当作是C程序,而g++当作是c++程序:后缀为.cpp的,两者都会认为 ...
- 虚拟机中安装MAC OS X教程(适用所有电脑方法,特别是cpu不支持硬件虚拟化的电脑)
前言 之前写了一篇在Windows上搭建Object-C开发环境,并且写了一个HelloWorld程序.但真正开发苹果软件是在MAC OS X系统中(以下简称OSX)中.买不起MacBook,也没有O ...
- 程序员应该懂的ip地址知识汇总
1.A类ip由1字节(1字节是8位2进制数)的网络地址和3字节的主机地址组成,网络地址最高位必须是0,地址范围是从1.0.0.0到126.0.0.0,所以A类网络地址有126个,每个网络能容纳至少2^ ...
- XSS构造技巧
利用字符编码: 百度曾经出过一个XSS漏洞,在一个<script>标签中输出一个变量,其中转义了双引号: var redirectUrl="\";alert(/XSS/ ...
- 在 Linux 下执行安装 bin 文件
原文: http://www.linuxidc.com/Linux/2014-03/98541.htm