zoukankan      html  css  js  c++  java
  • [CF1329C] Drazil Likes Heap

    [CF1329C] Drazil Likes Heap - 贪心

    Description

    定义一种堆的删除操作:对节点x操作,相当于从x出发,每次向大儿子走,直到走到叶子节点,删掉叶子节点,把路径上(除x外)每个值都向上移一步,最后把x原本的值覆盖掉。将大顶堆从高度h降低到g,必须应用题中的算法保证它们的和最小,输出和,并且输出被删除操作的序号。

    Solution

    不断对根节点执行算法删除操作,如果根不能删了(再删就会导致 g 层有空位)就递归处理左右子树

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    const int N = 5000005;
    
    int h, g, a[N];
    vector<int> ans, res;
    
    void del(int p)
    {
        if (a[p * 2] == 0 && a[p * 2 + 1] == 0)
        {
            a[p] = 0;
            return;
        }
        if (a[p * 2] < a[p * 2 + 1])
        {
            a[p] = a[p * 2 + 1];
            del(p * 2 + 1);
        }
        else
        {
            a[p] = a[p * 2];
            del(p * 2);
        }
    }
    
    int get_leaf(int p)
    {
        if (a[p * 2] == 0 && a[p * 2 + 1] == 0)
        {
            return p;
        }
        if (a[p * 2] < a[p * 2 + 1])
        {
            return get_leaf(p * 2 + 1);
        }
        else
        {
            return get_leaf(p * 2);
        }
    }
    
    void divide(int p)
    {
        if (!p)
            return;
        if (p >= (1 << g))
            return;
        while (get_leaf(p) >= (1 << g))
        {
            ans.push_back(p);
            res.push_back(a[p]);
            del(p);
        }
        divide(p * 2);
        divide(p * 2 + 1);
    }
    
    void solve()
    {
        cin >> h >> g;
        int n = (1 << h) - 1;
        for (int i = 1; i <= 4 * n; i++)
            a[i] = 0;
        for (int i = 1; i <= n; i++)
            cin >> a[i];
        int sum = 0;
        for (int i = 1; i <= n; i++)
            sum += a[i];
        divide(1);
        for (auto i : res)
            sum -= i;
        cout << sum << endl;
        for (auto i : ans)
            cout << i << " ";
        cout << endl;
        ans.clear();
        res.clear();
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
        int t;
        cin >> t;
        while (t--)
        {
            solve();
        }
    }
    
  • 相关阅读:
    UEFI手札
    ARM非对齐访问和Alignment Fault
    PCIE手札
    开始→运行(cmd)命令大全
    关于C#静态构造函数的几点说明
    网址
    python并发编程之多进程理论部分
    第九篇:网络编程
    第八篇:异常处理
    第七篇:面向对象高级
  • 原文地址:https://www.cnblogs.com/mollnn/p/14565169.html
Copyright © 2011-2022 走看看