P2073 送花

题目背景

小明准备给小红送一束花,以表达他对小红的爱意。他在花店看中了一些花,准备用它们包成花束。

题目描述

这些花都很漂亮,每朵花有一个美丽值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

说明

对于20%数据,操作数<=100,1<=W,C<=1000。

对于全部数据,操作数<=100000,1<=W,C<=1000000。

此题可谓练习线段树、Set、Treap、Splay的好题。

线段树做法:离线读取所有添加数据和操作,删除的时候向下dfs结束后向上更新即可。需要维护四个值,耐心写!猥琐发育别浪!

细节:别把美丽和价钱反了

   左移右移别手残(比如我)

     别忘了long long

以上。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 inline int max(int a,int b) {return a > b ? a : b;}
  7 inline int min(int a,int b) {return a > b ? b : a;}
  8 const int MAXN = 100000 + 10;
  9 inline void read(long long &x){
 10     x = 0;char ch = getchar();char c = ch;
 11     while(ch > '9' || ch < '0')c = ch, ch = getchar();
 12     while(ch >= '0' && ch <= '9')x = x * 10 + ch - '0',ch = getchar();
 13     if(c == '-')x = -x;
 14 }
 15 long long work[MAXN],num[MAXN][2],tmp,n,m;bool b[1000000 + 10];
 16 struct STNODE{
 17     long long l,r,max,min,sum,ssum;
 18 }stnode[(MAXN << 2 )+ 10];
 19 void build(int o = 1, int l = 1, int r = m){
 20     stnode[o].l = l;stnode[o].r = r;
 21     if(l == r){
 22         stnode[o].max = l;
 23         stnode[o].min = l;
 24         stnode[o].sum = num[l][1];
 25         stnode[o].ssum = num[l][0];
 26         return;
 27     }
 28     int mid = (l + r) >> 1;
 29     build(o << 1, l, mid);
 30     build(o << 1 | 1, mid + 1, r);
 31     if(num[stnode[o << 1].max][0] > num[stnode[o << 1 | 1].max][0])stnode[o].max = stnode[o << 1].max;
 32     else stnode[o].max = stnode[o << 1 | 1].max;
 33     if(num[stnode[o << 1].min][0] < num[stnode[o << 1 | 1].min][0])    stnode[o].min = stnode[o << 1].min;
 34     else stnode[o].min = stnode[o << 1 | 1].min;
 35     stnode[o].sum = stnode[o << 1].sum + stnode[o << 1 | 1].sum;
 36     stnode[o].ssum = stnode[o << 1].ssum + stnode[o << 1 | 1].ssum;
 37 }
 38 void cutoff(int p, int o = 1){
 39     int l = stnode[o].l;int r = stnode[o].r;
 40     if(l == r && l == p){
 41         stnode[o].ssum = stnode[o].sum = stnode[o].max = stnode[o].min = 0;
 42         return;
 43     }
 44     int mid = (l + r) >> 1;
 45     if(mid >= p) cutoff(p, o << 1);
 46     else cutoff(p, o << 1 | 1);
 47     stnode[o].sum = 0;
 48     stnode[o].ssum = 0;
 49     stnode[o].sum = stnode[o << 1].sum + stnode[o << 1 | 1].sum;
 50     stnode[o].ssum = stnode[o << 1].ssum + stnode[o << 1 | 1].ssum;
 51     if(num[stnode[o << 1].max][0] > num[stnode[o << 1 | 1].max][0]) stnode[o].max = stnode[o << 1].max;
 52     else stnode[o].max = stnode[o << 1 | 1].max;
 53     if(stnode[o << 1].min == 0 && stnode[o << 1 | 1].min == 0) stnode[o].min = 0;
 54     else if(stnode[o << 1].min == 0) stnode[o].min = stnode[o << 1 | 1].min;
 55     else if(stnode[o << 1 | 1].min == 0) stnode[o].min = stnode[o << 1].min;
 56     else {
 57         if(num[stnode[o << 1].min][0] < num[stnode[o << 1 | 1].min][0]) stnode[o].min = stnode[o << 1].min;
 58         else stnode[o].min = stnode[o << 1 | 1].min;
 59     }
 60 }
 61 int query_max(int ll,int rr,int o = 1){
 62     int ans1 = 0;int ans2 = 0;
 63     int l = stnode[o].l;int r = stnode[o].r;
 64     if(l >= ll && r <= rr) return stnode[o].max;
 65     int mid = (l + r) >> 1;
 66     if(mid >= ll) ans1 = query_max(ll, rr, o << 1);
 67     if(mid < rr) ans2 = query_max(ll, rr, o << 1 | 1);
 68     if(ans1 == 0 && ans2 == 0) return 0;
 69     if(num[ans1][0] > num[ans2][0]) return ans1;
 70     else return ans2;
 71 }
 72 int query_min(int ll,int rr,int o = 1){
 73     int ans1 = 0;int ans2 = 0;
 74     int l = stnode[o].l;int r = stnode[o].r;
 75     if(l >= ll && r <= rr) return stnode[o].min;
 76     int mid = (l + r) >> 1;
 77     if(mid >= ll) ans1 = query_min(ll, rr, o << 1);
 78     if(mid < rr) ans2 = query_min(ll, rr, o << 1 | 1);
 79     if(ans1 == 0 && ans2 == 0) return 0;
 80     else if(ans1 == 0) return ans2;
 81     else if(ans2 == 0) return ans1;
 82     else {
 83         if(num[ans1][0] < num[ans2][0]) return ans1;
 84         else return ans2;
 85     }
 86 }
 87 int main(){
 88         read(tmp);
 89     while(tmp != -1){
 90         n ++;
 91         if(tmp == 1){m ++;read(num[m][1]);read(num[m][0]);}
 92         else if(tmp == 2) work[n] = 1;
 93         else work[n] = 2;
 94         read(tmp);
 95     }
 96     if(m >= 1) build();
 97     int j = 0;int len = 0;
 98     for(int i = 1;i <= n;i ++){
 99         if(work[i] == 1 && len < j){
100             int a = query_max(1, j);
101             cutoff(a);
102             b[num[a][0]] = false;
103             len ++;
104         }
105         else if(work[i] == 2 && len < j){
106             int a = query_min(1, j);
107             cutoff(a);
108             b[num[a][0]] = false;
109             len ++;
110         }
111         else if(!work[i]){
112             j ++;
113             if(!b[num[j][0]]) b[num[j][0]] = true;
114             else cutoff(j);
115         }
116     }
117     printf("%lld %lld", stnode[1].sum, stnode[1].ssum);
118     return 0;
119 }

转载于:https://www.cnblogs.com/huibixiaoxing/p/6959437.html

洛谷P2073 送花 [2017年6月计划 线段树01]相关推荐

  1. 洛谷P2826 [USACO08NOV]光开关Light Switching [2017年6月计划 线段树02]

    P2826 [USACO08NOV]光开关Light Switching 题目描述 Farmer John tries to keep the cows sharp by letting them p ...

  2. 洛谷P2258 子矩阵[2017年5月计划 清北学堂51精英班Day1]

    题目描述 给出如下定义: 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵. 例如,下面左图中选取第2.4行和第2.4.5列交叉位置的元素 ...

  3. [洛谷P2073] 送花

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

  4. 【洛谷5251】[LnOI2019] 第二代图灵机(线段树+ODT)

    点此看题面 大致题意: 有单点修改数字和区间着色两种修改操作,询问你某段区间内包含所有颜色且数字和最小的子区间的数字和,或某段区间内没有重复颜色且数字和最大的子区间的数字和.数据随机. \(ODT\) ...

  5. 【洛谷】P3919 【模板】可持久化线段树(主席树)

    题目 传送门:QWQ 分析 主席树的模板,囤着 代码 #include <bits/stdc++.h> using namespace std; const int N=1000010; ...

  6. 洛谷.3919.[模板]可持久化数组(可持久化线段树/平衡树)

    题目链接 //利用先前的根节点建树 想一下不难写. #include <cstdio> #include <cctype> //#define gc() getchar() # ...

  7. 【洛谷AT2442】フェーン現象(Foehn Phenomena)【线段树】

    linklinklink 分析: 都说是裸差分 那就线段树做( 海拔的上升与下降 就区间修改 答案就单点查询 具体的就跟题意模拟了 然后注意a0a_0a0​是000 那n,x,yn,x,yn,x,y啥 ...

  8. 洛谷P3120 [USACO15FEB]牛跳房子(动态开节点线段树)

    题意 题目链接 Sol \(f[i][j]\)表示前\(i\)行\(j\)列的贡献,转移的时候枚举从哪里转移而来,复杂度\(O(n^4)\) 然后考虑每一行的贡献,动态开节点线段树维护一下每种颜色的答 ...

  9. 洛谷P4559 [JSOI2018]列队 【70分二分 + 主席树】

    题目链接 洛谷P4559 题解 只会做\(70\)分的\(O(nlog^2n)\) 如果本来就在区间内的人是不用动的,区间右边的人往区间最右的那些空位跑,区间左边的人往区间最左的那些空位跑 找到这些空 ...

最新文章

  1. 安装MMCV和MMDET
  2. 汇编中的length(返回利用dup定义的数组中的元素个数,即重复操作符dup前的count值)
  3. matlab中quat2angle,RPY_Euler_Quaternion_AngleAxis角度转化:Matlab、Python、Halc
  4. 【转】DCOM远程调用权限设置
  5. 状态目标bfs+哈希表 + 三杯水
  6. MySQL 是如何解决幻读的
  7. 20151212Jquery 工具函数代码备份
  8. 科学计算机恢复初始化,快速解决Windows 10系统还原一直初始化或卡住的方法!...
  9. 百度网盘怎么用迅雷下载
  10. 考试反思计算机专业,计算机专业期中考试分析与反思发
  11. 解决电脑蓝牙连不上问题
  12. Xftp的下载和安装(超详细)
  13. 如何理解实时频谱分析仪的几个“带宽”参数(1)——实时带宽(RTBW)
  14. ligerui 表格滚动条放在表格里,固定表头
  15. vim的设置文档【我的】
  16. 视频监控一般都存储在哪里?如何实现云端集中存储?
  17. 怎么使用计算机计算公式,科学计算器的使用方法 科学计算器的使用指导
  18. Autofac程序集注入
  19. MPLAB-IDE-C语言编程代码实例-分析
  20. 2020杭电计算机考研复试面试

热门文章

  1. 请问学习前端最有效的办法是什么?
  2. 零基础开始学 Web 前端开发,有什么建议吗?
  3. 今天讲个小故事,Javascript诞生记
  4. 资深前端工程师:裁人后,我总结了 7 个必备技能
  5. 商品进销差价_商品进销差价如何核算?
  6. 16 bit float 存储_小数在内存中是如何存储的,揭秘诺贝尔奖级别的设计(长篇神文)...
  7. Hook鼠标和键盘的使用
  8. maven java jar_如何去maven仓库下载jar包
  9. MySQL实验7存储过程_mySQL(7)-存储过程
  10. cmake 多次编译_Part01_CMakeLists构建管理多个模块的C代码