1.17堆模板,黑匣子(对顶堆应用,找动态第i大的数),合并果子(哈夫曼树),荷马史诗(多叉哈夫曼树,补空叶子结点)

news2024/11/15 13:09:34

二叉堆树状数组

P3378 【模板】堆

向上调整唯一,向下调整要看孩子

#include<iostream>
#include<iomanip>
#include<vector>
#include<string>
using namespace std;
const int maxn = 1e6 + 3;
int h[maxn], n, op, num, cnt = 0;
void swap(int x, int y) {
    int t = h[x];
    h[x] = h[y];
    h[y] = t;
}
void up(int x) {
    int p = x / 2;
    while (p >= 1&&h[p]>h[x]) {
        swap(x, p);
        x = p;
        p = x / 2;
    }
}
void down(int x) {
    int c = x * 2;
    while (c <= cnt) {
        if (c + 1 <= cnt && h[c + 1] < h[c]) {
            c++;
        }
        if (h[c] < h[x]) {
            swap(c, x);
            x = c;
            c = x * 2;
        }
        else {
            break;
        }
    }
}
void del() {
    h[1] = h[cnt--];
    down(1);
}
int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> op;
        if (op == 1) {
            cin >> num;
            h[++cnt] = num;
            up(cnt);
        }
        else if (op == 2) {
            cout << h[1] << endl;
        }
        else {
            del();
        }
    }
    return 0;
}

P1801 黑匣子

大顶堆小顶堆

大顶堆里的堆顶是最大的元素,小顶堆的是最小的元素,那么i个元素的大顶堆和j个元素的小顶堆拼在一起,堆顶就是指向i+j的数列中第i大的元素

就是说,大顶堆是第i大前面的数,小顶堆是第i大后面的数

插入元素的时候,如果比此时第i大大的话,就直接放入小顶堆中

如果比第i大小,就放入大顶堆,一旦大顶堆的大小超过i,就pop掉大顶堆堆顶的元素,使其进入小顶堆

就是说,小顶堆的堆顶是第i大,但如果是第i大,就说明大顶堆里一定有i-1个元素,即大顶堆里一定只维护着i-1个元素

那就是说,第一次插入的时候,插到小顶堆里,

然后第i次插入的时候,判断插入元素与小顶堆堆顶的大小关系,如果大的话,就不影响第i大,就直接放入小顶堆;否则,插入大顶堆中,并把大顶堆的堆顶插入到小顶堆中并删除,维护大顶堆大小不变,为i-1,这样就能始终保证大顶堆大小为i-1,小顶堆堆顶为第i大的元素

有n次get操作,就说明最后要的是第n大的数,在之前,每次get后都会获得越来越大的第i大的数

每次就往大顶堆里放,一旦大顶堆满了,就溢出进小顶堆里

#include<iostream>
#include<iomanip>
#include<vector>
#include<string>
#include<queue>
using namespace std;
const int maxn = 2e5 + 3;
priority_queue<int>da;
priority_queue<int, vector<int>, greater<int>>xiao;
int m, n, num[maxn], op[maxn], cnt;
int main() {
    cin >> m >> n;
    for (int i = 1; i <= m; i++)cin >> num[i];
    int begin = 1;
    for (int i = 1; i <= n; i++) {//这个就表示此时大顶堆的限度
        cin >> cnt;//表示这个标杆前的数据,都对应的大顶堆大小是i
        for (int j = begin; j <= cnt; j++) {
            da.push(num[j]);
            if(da.size() == i) {//满了i就溢出,就是说最大为i-1
                xiao.push(da.top());
                da.pop();
            }
        }
        cout << xiao.top() << endl;
        begin = cnt + 1;//下一次的起点,
        da.push(xiao.top());//下次要找的就是更大的数据,此时就提前先把大顶堆的容量扩容为i
        xiao.pop();//那么下次检测的时候由于i++,实际上是要i+1才会溢出,就是说这里扩容后
    }//在下次时是不会溢出的,溢出是插入数据后才会溢出,即到达i+1
    return 0;
}

P1090 [NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G

就是一个哈夫曼树

#include<iostream>
#include<iomanip>
#include<vector>
#include<string>
#include<queue>
using namespace std;
priority_queue<int, vector<int>, greater<int>>q;
int n, ans = 0, temp;
int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> temp;
        q.push(temp);
    }
    while (q.size() != 1) {
        int a = q.top();
        q.pop();
        int b = q.top();
        q.pop();
        q.push(a + b);
        ans += (a + b);
    }
    cout << ans;
    return 0;
}

P2168 [NOI2015] 荷马史诗

类似于哈夫曼树,哈夫曼编码,就是让出现频率最高的字用最短的,出现频率低的用长的

如果是k叉树的话,将k个结点合并为1个,那就是每次减少k-1个结点,一共要将N个结点合并成1个

每次减少k-1个,一共要减少n-1个,所以如果n-1不是k-1的倍数,那么在最后一次的时候就会不够k个,所以就要补充相应数量的空结点来使其达到k-1的倍数

拿普通二叉哈夫曼树举例就是说,一共有n个结点,最后要合并成1个,就是要减少n-1个结点,每次的话,由于是二分,所以每次只会减少1个,所有就要n-1次合并

如果是三分的话,每次会减少两个,那么要减少n-1个结点,就要(n-1)/2次合并

还有就是要注意,是要保证总长度最短,就是说如果权重相同的话,那么优先让高度低的组

而不是让高度高的组,这样的话可以稳住高度差,

因为在哈夫曼树当中,高度就意味着是编码的长度

#include<iostream>
#include<iomanip>
#include<vector>
#include<string>
#include<queue>
using namespace std;
int n, k;
long long temp,ans = 0;
struct node {
    long long w, h;
    node(long long  nw, long long nh) :w(nw), h(nh) {}
};
struct cmp {
    bool operator()(node a, node b) {
        if (a.w != b.w) {
            return a.w > b.w;
        }
        else {
            return a.h > b.h;
        }
    }
};
priority_queue<node, vector<node>, cmp>q;
int main() {
    cin >> n >> k;
    for (int i = 1; i <= n; i++) {
        cin >> temp;
        q.push(node(temp, 1));
    }
    while ((q.size() - 1) % (k - 1)) {
        q.push(node(0, 1));
    }
    while (q.size() != 1) {
        long long maxh = 0, sum = 0;
        for (int i = 1; i <= k; i++) {
            sum += q.top().w;
            maxh = max(maxh, q.top().h);
            q.pop();
        }
        ans += sum;
        q.push(node(sum, maxh + 1));
    }
    cout << ans << endl;
    cout << q.top().h - 1;
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1409933.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++入门到精通】智能指针 shared_ptr循环引用 | weak_ptr 简介及C++模拟实现 [ C++入门 ]

阅读导航 引言一、std::shared_ptr的循环引用1. 概念2. 示例分析 二、std::weak_ptr1. 简介2. weak_ptr模板类提供的成员方法3. 使用示例&#xff08;1&#xff09;weak_ptr指针的创建&#xff08;2&#xff09;完整示例&#xff08;解决上面循环引用问题&#xff09; 4. C模拟…

幻兽帕鲁PalWorld服务器搭建教程,1分钟开服,纯小白教程,无需基础

雨云面板服快速开幻兽帕鲁PalWorld服务器的教程&#xff0c;配置文件修改方法和配置项中文注释。 最近这游戏挺火&#xff0c;很多人想跟朋友联机&#xff0c;如果有专用服务器&#xff0c;就不需要房主一直开着电脑&#xff0c;稳定性也好得多。 幻兽帕鲁简介 《幻兽帕鲁》…

Revit二次开发 设置材质

设置此处材质&#xff0c;需要在材质浏览器中创建材质&#xff0c;根据材质名字设置此材质。 代码如下&#xff1a; Material material new FilteredElementCollector(doc).OfClass(typeof(Material)).FirstOrDefault(x > x.Name "窗框") as Material; Element…

掼蛋的文化价值

近几年&#xff0c;掼蛋成为人们在各种场合休闲娱乐时的首选&#xff01;掼蛋的魅力在于它不仅是一款简单有趣的游戏&#xff0c;更是中国传统文化和智慧的缩影&#xff01;它所积淀的文化价值、所蕴含的文化元素、所散发的文化气息具体包括&#xff1a; 1.社交文化&#xff1a…

android camera的使用以及输出的图像格式

一、Camera 1.1、结合SurfaceView实现预览 1.1.1、布局 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-au…

3d导模型赋予材质方法---模大狮模型网

给3D模型赋予材质的方法可以根据您使用的软件和工作流程而有所不同。以下是一般的步骤&#xff0c;您可以根据自己的情况进行调整&#xff1a; 准备模型&#xff1a;首先&#xff0c;确保您的模型已经完全建模并进行了UV映射。UV映射是将2D纹理坐标应用到3D模型表面的过程&…

对 MODNet 网络结构直接剪枝的探索

文章目录 1 写在前面2 遇到问题3 解决方案4 探索过程4.1 方案一4.2 方案二4.3 方案三 5 疑惑与思考5.1 Q15.2 Q2 1 写在前面 在前面的文章中&#xff0c;笔者与小伙伴们分享了对 MODNet 主干网络部分以及其余分支分别剪枝的探索历程&#xff0c;即先分解、再处理、后融合的手法…

DB2数据库,时间类型插入数据

DB2数据库,时间类型插入数据 1、TIMESTAMP类型 1.1、创建表 CREATE TABLE BI_varchar ( id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1 ), hide_zero varchar(1000), simulation_cphone_de varchar(1000), disorder_de varchar(…

Cortex-M4 处理器 内存模型

内存模型 处理器有一个固定的默认内存映射&#xff0c;提供最多4GB的可寻址内存。 SRAM和外设的区域包括可选的位带区域。 位带提供了对位数据的原子操作 处理器为核心外设寄存器保留专用外设总线&#xff08;PPB&#xff09;地址范围的区域。 内存区域、类型和属性 内存映…

3D打印机 拓竹A1 Combo 开箱体验

拓竹&#xff08;Bambu Lab&#xff09;A1 Combo FDM 3D打印机开箱体验。 最近想玩玩3D打印&#xff0c;所以入手了一台拓竹A1 Combo的3D打印机&#xff0c;A1 Combo对比A1多了个AMS lite&#xff0c;支持多色打印&#xff08;4种颜色&#xff09;&#xff0c;京东买的&#x…

Redis——关于它为什么快?使用场景?以及使用方式?为何引入多线程?

目录 1.既然redis那么快&#xff0c;为什么不用它做主数据库&#xff0c;只用它做缓存&#xff1f; 2.Redis 一般在什么场合下使用&#xff1f; 3.redis为什么这么快&#xff1f; 4.Redis为什么要引入了多线程&#xff1f; 1.既然redis那么快&#xff0c;为什么不用它做主数据…

在线SM4加密/解密工具

在线SM4加密/解密 - BTool在线工具软件&#xff0c;为开发者提供方便。在线SM4加密/解密工具支持快速、便捷地对数据进行SM4算法加密与解密。适用于各类业务场景&#xff0c;确保信息安全传输&#xff0c;操作简易直观&#xff0c;只需几步即可完成加解密过程。采用国家标准SM4…

Webpack5 基本使用 - 1

Webpack 是什么 webpack 的核心目的是打包&#xff0c;即把源代码一个一个的 js 文件&#xff0c;打包汇总为一个总文件 bundle.js。 基本配置包括mode指定打包模式&#xff0c;entry指定打包入口&#xff0c;output指定打包输出目录。 另外&#xff0c;由于 webpack默认只能打…

Python工具:pathlib

文件的路径实际上是一件很困扰的时间&#xff08;各种平台有时候规则不一样&#xff0c;有时候还需要考虑字符转义的问题&#xff09;&#xff0c;因此我直接推荐使用模块 pathlib&#xff0c;当然&#xff0c;如果您不介意的话&#xff0c;可以使用 os.path 做较为低级的路径操…

蓝桥杯(Python)每日练Day5

题目 OJ1229 题目分析 题目完全符合栈的特征&#xff0c;后进先出。如果能够熟练使用列表的9种方法那么这道题很容易解出。 题解 a[]#存衣服 nint(input()) for i in range(n):llist(input().split())#判断每一步的操作if len(l[0])2:a.append(l[1])else:while a.pop()!l…

不停机迁移,TDengine 在 3D 打印技术中的“焕新”之路

小T导读&#xff1a;自 2021 年我们正式使用 TDengine 至今已接近三年&#xff0c;现在 TDengine 已经成熟应用于我们多个项目当中&#xff0c;凭借着强大的读写存储能力&#xff0c;为我司多项业务的核心数据保驾护航。近期我们团队刚好完成 TDengine 2.x 到 3.x 的数据迁移&a…

Redisson 分布式锁可重入的原理

目录 1. 使用 Redis 实现分布式锁存在的问题 2. Redisson 的分布式锁解决不可重入问题的原理 1. 使用 Redis 实现分布式锁存在的问题 不可重入&#xff1a;同一个线程无法两次 / 多次获取锁举例 method1 执行需要获取锁method2 执行也需要&#xff08;同一把&#xff09;锁如…

Redis面试

1.说说什么事redis Redis是一种基于键值对的NoSql数据库。 Redis中的value支持string&#xff08;字符串&#xff09;、hahs&#xff08;哈希&#xff09;、list、set、zset&#xff08;有序集合&#xff09;、bitmaps&#xff08;位图&#xff09;&#xff0c;HyperLoglog等数…

树的学习day01

树的理解 树是一种递归形式的调用 树是由于多个结点组成的有限集合T 树中有且仅有一个结点称为根 当结点大于1的时候&#xff0c;往往其余的结点为m个互不相交的有限个集合T1,…,Tm&#xff0c;每个互不相交的有限集合本身右是一棵树&#xff0c;称为这个根的子树 空树也是树 关…

【Web前端开发基础】CSS3之空间转换和动画

CSS3之空间转换和动画 目录 CSS3之空间转换和动画一、空间转换1.1 概述1.2 3D转换常用的属性1.3 3D转换&#xff1a;translate3d&#xff08;位移&#xff09;1.4 3D转换&#xff1a;perspective&#xff08;视角&#xff09;1.5 3D转换&#xff1a;rotate3d&#xff08;旋转&a…