【题目描述:】

这些花都很漂亮,每朵花有一个美丽值W,价格为C。

小明一开始有一个空的花束,他不断地向里面添加花。他有以下几种操作:

操作 含义

1 W C 添加一朵美丽值为W,价格为C的花。

3 小明觉得当前花束中最便宜的一朵花太廉价,不适合送给小红,所以删除最便宜的一朵花。

2 小明觉得当前花束中最贵的一朵花太贵,他心疼自己的钱,所以删除最贵的一朵花。

-1 完成添加与删除,开始包装花束

若删除操作时没有花,则跳过删除操作。

如果加入的花朵价格已经与花束中已有花朵价格重复,则这一朵花不能加入花束。

请你帮小明写一个程序,计算出开始包装花束时,花束中所有花的美丽值的总和,以及小明需要为花束付出的总价格。

【输入格式:】

若干行,每行一个操作,以-1结束。

【输出格式:】

一行,两个空格隔开的正整数表示开始包装花束时,花束中所有花的美丽值的总和。以及小明需要为花束付出的总价格。

/*
输入样例#1:
1 1 1
1 2 5
2
1 3 3
3
1 5 2
-1
输出样例#1:
8 5
*/

输入输出样例

【算法分析:】

方法一:红黑树.

  手写红黑树是不可能的,但是可以用stl里的map水(set好像也可以不过应该比map慢一些)

map里的key-value其实就是pair,而且map里的元素是有序的:

  默认按key从小到大排,所以求c的最值时应把make_pair(c, w)加入map

所以删除最小的元素就是删除map中的第一个元素,删除最大的元素就是删除map中的最后一个。

删除操作可以通过erase(iterator)来实现,定义一个map<int, int> a,

  则第一个元素的位置为a.begin()

  最后一个元素的位置就是 --a.end()

最后累加的时候通过迭代器遍历map,用a->first和a->second访问key, value的值

去重的话加一个bool数组去重就好

 1 //P2073 送花
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<map>
 6 #define mkp make_pair
 7 #define fi first
 8 #define se second
 9 using namespace std;
10
11 const int MAXN = 1000000 + 1;
12
13 map<int, int> a;
14 bool vis[MAXN];
15
16 int main() {
17     int fl, w, c;
18     while(scanf("%d", &fl) == 1 && fl != -1) {
19         if(fl == 1) {
20             scanf("%d%d", &w, &c);
21             if(vis[c]) continue;
22             a.insert(mkp(c, w));
23             vis[c] = 1;
24         }
25         if(fl == 2) {
26             if(!a.size()) continue;
27             map<int, int>::iterator it;
28             it = a.end();
29             --it; vis[it->fi] = 0;
30             a.erase(it);
31         }
32         if(fl == 3) {
33             if(!a.size()) continue;
34             map<int, int>::iterator it;
35             it = a.begin();
36             vis[it->fi] = 0;
37             a.erase(it);
38         }
39     }
40     long long sum1 = 0, sum2 = 0;
41     map<int, int>::iterator it;
42     for(it=a.begin(); it!=a.end();++it)
43         sum1 += it->se, sum2 += it->fi;
44     printf("%lld %lld\n", sum1, sum2);
45 }

map实现

方法二:堆

  要求最大值和最小值并删除,很容易想到通过堆来实现

开一个小根堆p1和一个大根堆p2,

vis[c]表示价格为c的花的美丽度,vis[c]=0表示没有这朵花

每次读入把c分别push进两个堆里,记录vis[c]

两个变量sum1, sum2分别累加c和w,

在删除的时候sum1, sum2要分别减去c和vis[c]

 1 //P2073 送花
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<queue>
 6 using namespace std;
 7
 8 const int MAXN = 1000000 + 1;
 9
10 int vis[MAXN];
11 priority_queue<int, vector<int>, greater<int> > q1;
12 priority_queue<int> q2;
13
14 int main() {
15     int fl, w, c;
16     long long sum1 = 0, sum2 = 0;
17     while(scanf("%d", &fl) == 1 && fl != -1) {
18         if(fl == 1) {
19             scanf("%d%d", &w, &c);
20             if(vis[c]) continue;
21             q1.push(c), q2.push(c);
22             vis[c] = w;
23             sum1 += w, sum2 += c;
24         }
25         if(fl == 2) {
26             while(!q2.empty() && !vis[q2.top()]) q2.pop();
27             if(q2.empty()) continue;
28             int t = q2.top();
29             sum1 -= vis[t];
30             sum2 -= t;
31             vis[t] = 0;
32             q2.pop();
33         }
34         if(fl == 3) {
35             while(!q1.empty() && !vis[q1.top()]) q1.pop();
36             if(q1.empty()) continue;
37             int t = q1.top();
38             sum1 -= vis[t];
39             sum2 -= t;
40             vis[t] = 0;
41             q1.pop();
42         }
43     }
44     printf("%lld %lld\n", sum1, sum2);
45 }

堆实现

转载于:https://www.cnblogs.com/devilk-sjj/p/9065586.html

【洛谷】【treap/堆】P2073 送花相关推荐

  1. 洛谷P2073 送花 [2017年6月计划 线段树01]

    P2073 送花 题目背景 小明准备给小红送一束花,以表达他对小红的爱意.他在花店看中了一些花,准备用它们包成花束. 题目描述 这些花都很漂亮,每朵花有一个美丽值W,价格为C. 小明一开始有一个空的花 ...

  2. 浅尝无旋Treap (基于洛谷P3391 文艺平衡树)

    说是浅尝吧,确实也挺浅的,完全是基于下面这道题写的↓ 洛谷P3391 自己去看题,我是懒得粘了... 分析 其实也没有什么好分析的,这就是一道Splay树的模板题,解决一般的Treap不能解决的区间维 ...

  3. 洛谷P2085ssl1411OJ1370-最小函数值【堆,贪心】

    前言 有一个东西卡了我一会 折叠N*或N+ 正整数集 (由全体正整数组成的集合) N*:={1,2,3,-,n,-} 题目 洛谷P2085 OJ1370 给出n个ai,bi,ci.定义一个函数 fi( ...

  4. 洛谷 P3378 【模板】堆

    2019-05-30 题目 : 洛谷 P3378 [模板]堆 : https://www.luogu.org/problemnew/show/P3378 题目描述 如题,初始小根堆为空,我们需要支持以 ...

  5. 升序堆和降序堆(优先队列) 洛谷1801

    1 // 洛谷1801 2 // 一个升序堆,一个降序堆 3 // 降序堆维护序列的前i个最小值 4 // 插如元素的时候,如果x小于降序堆最大值,则替换,并将最大值插入升序堆:否则,直接插入升序堆 ...

  6. 洛谷:P2832 行路难(堆优化Dijkstra(错解)bfs(正解) + 记录路径)

    洛谷:P2832 行路难 写这道题确实是行路难- 此题的最短路约束不只是边权,还有边数(每经过一条边,之后经过的边权值都 +1+1+1 ) 从期望的角度分析,我们肯定是想 尽可能走的路程越短,走得路径 ...

  7. 洛谷2085-最小函数值-python-(二叉堆)

    最近在学习dijkstra最短路算法,朴素算法的时间复杂度是O(N^2),也就是说当数据量达到1e5的时候,1S可能就不够了,因此我们需要对算法进行优化,如果能让时间复杂度变为O(NlogN)的话,一 ...

  8. 洛谷_P3371 【模板】单源最短路径(弱化版)_dijkstra_堆优化

    洛谷_P3371 [模板]单源最短路径(弱化版)_dijkstra_堆优化 // dijkstra最短路算法_堆优化 #include<bits/stdc++.h> using names ...

  9. 洛谷日报 2020年3月前索引

    2020 2019 2018 感觉洛谷日报全是干货!!!先记下来再说 2020 年洛谷日报索引 3 月 #260[dove]Church 编码(和 Lambda 演算) https://www.luo ...

  10. 洛谷日报索引(2020、2019、2018)

    历年洛谷日报索引 2020 2019 2018 感觉洛谷日报全是干货!!!先记下来再说 2020 年洛谷日报索引 3 月 #260[dove]Church 编码(和 Lambda 演算) https: ...

最新文章

  1. 怎么使图表居中显示_文字怎么排版又精美又好看?
  2. “禁止大数据杀熟”拟入法!个性化推荐功能也应提供拒绝选项
  3. 一起学设计模式 - 命令模式
  4. matlab中quiver,matlab quiver 比例尺
  5. fir.im Weekly - 2016 年 Android 最佳实践列表 1
  6. redis作用_Java高级架构笔记——实现故障恢复自动化:详解Redis哨兵技术
  7. 视频结构化+AI,智能安防的未来
  8. Android 获取SN号
  9. php 时间 增加天数,php实现当前时间加天数的方法
  10. 开源OA办公平台教程:手机APP指纹认证的配置
  11. 9 椭圆曲线密码体制
  12. 生活随记 - 火星梦
  13. Excel怎么一次性删除数据末尾的空格
  14. 嵌入式软件之应用调试
  15. 亲历NSDI 2013
  16. c语言零错误零警告,C语言 g警告:无符号表达式的比较0始终为false
  17. 聚苯乙烯/超高分子量聚乙烯合金包覆多孔SiO复合微球/聚苯乙烯微球载金属卟啉的研究
  18. 屏蔽掉Linux上运行Spark(Python版)时的多余信息(INFO)
  19. Java 调用Python+Opencv实现图片定位
  20. 全链路压测核心技术解析

热门文章

  1. 可以载入史册的新名词:市场经济(蝳品经济)的上瘾依赖特性
  2. 软件基本功:代码要有道理
  3. undefined reference to `crypto_get_random'
  4. C++两个类互相引用,如何处理最好
  5. 天人感应是常见的自然规律
  6. 从山顶透过云层看城市
  7. const 成员函数
  8. AD PCB板子长度宽度 PCB板子尺寸大小信息
  9. 我的世界服务器皮肤怎么用文件夹,我的世界怎么用皮肤文件,怎么通过文件夹更改皮肤...
  10. c++ 打印日志信息