E. Drazil Likes Heap 发表于 2020-04-20 | 阅读数 有一个高度为$h$的大顶堆,要求恰好删除掉$2^h - 2^g$个结点后,使得剩下一个 $g$ 的完全大顶堆。 结点总权值最大。 显然是删最大的,显然从最大开始能删就删,结束了?模拟一下? 代码 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677#include <bits/stdc++.h>using namespace std;typedef long long ll;#define pii pair<int, int>#define mk make_pairconst int N = 4e6 + 10;const int mod = 1e9 + 7;int a[N];int getlast(int x){ //cout << x << endl; if (!a[x << 1] && !a[x << 1 | 1]) return x; else if (a[x << 1] < a[x << 1 | 1]) { return getlast(x << 1 | 1); } else { return getlast(x << 1); }}void del(int x){ if (!a[x << 1] && !a[x << 1 | 1]) a[x] = 0; else if (a[x << 1] < a[x << 1 | 1]) { a[x] = a[x << 1 | 1]; del(x << 1 | 1); } else { a[x] = a[x << 1]; del(x << 1); }}int h, g;int main(){ int T; scanf("%d", &T); while (T--) { scanf("%d%d", &h, &g); vector<int> ans; for (int i = 1; i <= 1 << (h + 1); i++) a[i] = 0; for (int i = 1; i < (1 << h); i++) scanf("%d", &a[i]); // del(1); // cout << getlast(1) << endl; // del(1); // cout << getlast(1) << endl; for (int i = 1; i < (1 << g); i++) { while (getlast(i) > ((1 << g) - 1)) { //cout << "----" << endl; ans.push_back(i); del(i); } } // } ll sum = 0; for (int i = 1; i < (1 << g); i++) sum += a[i]; printf("%lld\n", sum); for (int x : ans) printf("%d ", x); printf("\n"); }}