题目链接

题意

给出一个高度为 h 的大根堆, 要求弹出其中若干个数后高度变为 g, 并且变化前后大根堆都是满二叉树. 问新的大根堆所有数之和的最小值, 并要给出一种弹出数的操作序列(节点序号). h, g ≤ 20. 堆的弹出过程见如下代码:

题解

考虑新堆的每个节点的可能最小结果: 如果是叶子节点, 那么最小是取它的子树中最小的数; 否则, 取子树中比两个儿子大的数中的最小值.

那么, 能否能得到这个每个节点都取到最小值的堆呢, 回答是肯定的. 我们在得知哪些数字会留下后, 是要把其他点弹出的. 弹出这些数后, 我们还需要考虑新堆是不是满二叉树. 按序号从小到大考虑每个节点, 会发现(这个过程不太好描述, 主要还是堆的性质)每个节点最后的结果一定是以它为根的子树中剩余数字的最大值(被祖先节点使用的话是要移除的), 既然每个节点都有数字, 这个堆自然是满二叉堆.

要得到新堆的每个节点的数字, 可以从下到上维护每个节点的子树的序列. 每次合并都是 O(len) (len为序列长度) 的, 总的时间复杂度为 O(nlogn). 要输出操作序列时, 可以从下往上弹出不需要的数字, 这样不会影响到祖先的结构.

代码

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inc(i, l, r) for (int i = l; i <= r; i++)
#define dec(i, l, r) for (int i = l; i >= r; i--) const int maxn = (1 << 20) + 5; int t, h, g;
int val[maxn], nxt[maxn];
vector<int> sub[maxn]; inline vector<int> Merge(vector<int> v1, vector<int> v2, int id) {
int sz1 = v1.size(), sz2 = v2.size();
vector<int> r(sz1 + sz2 + 1);
for (int i = 0, j = 0; i + j < sz1 + sz2;) {
if (j == sz2 || i < sz1 && v1[i] < v2[j]) {
r[i + j] = v1[i];
i++;
} else {
r[i + j] = v2[j];
j++;
}
}
r[sz1 + sz2] = val[id];
return r;
} int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> t;
while (t--) {
cin >> h >> g;
inc(i, 1, (1 << h) - 1) cin >> val[i];
inc(i, 1 << h - 1, (1 << h) - 1) sub[i] = vector<int>(1, val[i]);
dec(i, (1 << h - 1) - 1, 1) {
sub[i] = Merge(sub[i << 1], sub[i << 1 | 1], i);
}
set<int> s;
ll sum = 0;
inc(i, 1 << g - 1, (1 << g) - 1) {
nxt[i] = sub[i][0];
s.insert(nxt[i]);
sum += nxt[i];
}
dec(i, (1 << g - 1) - 1, 1) {
inc(j, 0, (int)sub[i].size() - 1) if (sub[i][j] > nxt[i << 1] &&
sub[i][j] > nxt[i << 1 | 1]) {
nxt[i] = sub[i][j];
s.insert(nxt[i]);
sum += nxt[i];
break;
}
}
cout << sum << "\n";
dec(i, (1 << h) - 1, 1) {
if (s.find(val[i]) == s.end()) cout << i << " ";
}
cout << "\n";
}
}

Codeforces 1329C - Drazil Likes Heap(堆+贪心)的更多相关文章

  1. CF R631 div2 1330 E Drazil Likes Heap

    LINK:Drazil Likes Heap 那天打CF的时候 开场A读不懂题 B码了30min才过(当时我怀疑B我写的过于繁琐了. C比B简单多了 随便yy了一个构造发现是对的.D也超级简单 dp了 ...

  2. Codeforces 631 (Div. 2) E. Drazil Likes Heap 贪心

    https://codeforces.com/contest/1330/problem/E 有一个高度为h的大顶堆:有2h -1个不同的正整数,下标从1到2h−1,1<i<2h, a[i] ...

  3. Codeforces Round #631 div1C(或者div2E) Drazil Likes Heap 题解

    题目链接:https://codeforces.com/contest/1329/problem/C 或者:https://codeforces.com/contest/1330/problem/E ...

  4. #292 (div.2) D.Drazil and Tiles (贪心+bfs)

    Description Drazil created a following problem about putting  ×  tiles into an n × m grid: "The ...

  5. Heap堆的理解以及在IAR中如何设置堆的大小

    文章首发于浩瀚先森博客 堆栈的概念在脑海里已经存在有一段时间了,今天就测试来整理下Heap堆.栈以后再说. 堆区不像全局变量和局部变量总是有指定的内存大小,它是为了在程序运行时动态分配内存而设定的一块 ...

  6. java - Stack栈和Heap堆的区别

    首先分清楚Stack,Heap的中文翻译:Stack—栈,Heap—堆.         在中文里,Stack可以翻译为“堆栈”,所以我直接查找了计算机术语里面堆和栈开头的词语:        堆存储 ...

  7. Heap(堆)和stack(栈)有的区别是什么。

    java的内存分为两类,一类是栈内存,一类是堆内存.栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个 ...

  8. JAVA Stack栈和Heap堆的区别(转)

          首先分清楚Stack,Heap的中文翻译:Stack—栈,Heap—堆.         在中文里,Stack可以翻译为“堆栈”,所以我直接查找了计算机术语里面堆和栈开头的词语:      ...

  9. Codeforces 437C The Child and Toy(贪心)

    题目连接:Codeforces 437C  The Child and Toy 贪心,每条绳子都是须要割断的,那就先割断最大值相应的那部分周围的绳子. #include <iostream> ...

随机推荐

  1. Eureka 注册中心看这一篇就够了

    服务注册中心是服务实现服务化管理的核心组件,类似于目录服务的作用,主要用来存储服务信息,譬如提供者 url 串.路由信息等.服务注册中心是微服务架构中最基础的设施之一. 在微服务架构流行之前,注册中心 ...

  2. 正式学习MVC 05

    1.剃须刀模板razor的使用 1)混编 循环语法 @model List<MVCStudy.Models.Student> @{ ViewBag.Title = "List&q ...

  3. Spring-Boot-应用可视化监控

    图文简介 快速开始 1.Spring Boot 应用暴露监控指标[版本 1.5.7.RELEASE] 首先,添加依赖如下依赖: <dependency> <groupId>or ...

  4. iOS下的 Fixed BUG

    input 光标位置乱窜 固定式浮层内的输入框光标会发生偏移.即 fixed 定位的容器中输入框光标的位置显示不正确,没有正常地显示在输入框中,而是偏移到了输入框外面 可触发条件 页面body出现滚动 ...

  5. 原生js实现replace方法

    今天看到有人提问js的replace方法怎么实现的,自己就试了试js手册里的String对象的介绍replace大概是这样: string.replace(regexp, replacement) 第 ...

  6. 前端每日实战:20# 视频演示如何用纯 CSS 为母亲节创作一颗像素画风格的爱心

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/LmrZVX 可交互视频教程 此视频 ...

  7. FreeSql 插入数据,如何返回自增值

    FreeSql是一个功能强大的 .NET ORM 功能库,支持 .NetFramework 4.0+..NetCore 2.1+.Xamarin 等支持 NetStandard 所有运行平台. 以 M ...

  8. python学习记录_中断正在执行的代码,执行剪切板中的代码,键盘快捷键,魔术命令,输入和输出变量,记录输入和输出变量_

    2018-03-28 00:56:39 中断正在执行的代码 无论是%run执行的脚本还是长时间运行的命令ctrl + cIn [1]: KeyboardInterrupt 执行剪切板中的代码 ctrl ...

  9. 《一步步成为 Hacker_Day 01》

    环境搭建 传统运行模式 - 一台机器同时只能运行一个操作系统 |:----------|----------:| | 应用程序 | 应用程序 | |:----------|----------:| | ...

  10. promise迷你书-读书笔记

    Promise三种类型 Constructor 使用Promise构造器来实例化一个promise对象 var promise = new Promise(function(resolve,rejec ...