洛谷P2073 送花 [2017年6月计划 线段树01]
P2073 送花
题目背景
小明准备给小红送一束花,以表达他对小红的爱意。他在花店看中了一些花,准备用它们包成花束。
题目描述
这些花都很漂亮,每朵花有一个美丽值W,价格为C。
小明一开始有一个空的花束,他不断地向里面添加花。他有以下几种操作:
操作 含义
1 W C 添加一朵美丽值为W,价格为C的花。
3 小明觉得当前花束中最便宜的一朵花太廉价,不适合送给小红,所以删除最便宜的一朵花。
2 小明觉得当前花束中最贵的一朵花太贵,他心疼自己的钱,所以删除最贵的一朵花。
-1 完成添加与删除,开始包装花束
若删除操作时没有花,则跳过删除操作。
如果加入的花朵价格已经与花束中已有花朵价格重复,则这一朵花不能加入花束。
请你帮小明写一个程序,计算出开始包装花束时,花束中所有花的美丽值的总和,以及小明需要为花束付出的总价格。
输入输出格式
输入格式:
若干行,每行一个操作,以-1结束。
输出格式:
一行,两个空格隔开的正整数表示开始包装花束时,花束中所有花的美丽值的总和。以及小明需要为花束付出的总价格。
输入输出样例
1 1 1
1 2 5
2
1 3 3
3
1 5 2
-1
8 5
说明
对于20%数据,操作数<=100,1<=W,C<=1000。
对于全部数据,操作数<=100000,1<=W,C<=1000000。
此题可谓练习线段树、Set、Treap、Splay的好题。
线段树做法:离线读取所有添加数据和操作,删除的时候向下dfs结束后向上更新即可。需要维护四个值,耐心写!猥琐发育别浪!
细节:别把美丽和价钱反了
左移右移别手残(比如我)
别忘了long long
以上。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
inline int max(int a,int b) {return a > b ? a : b;}
inline int min(int a,int b) {return a > b ? b : a;}
const int MAXN = + ;
inline void read(long long &x){
x = ;char ch = getchar();char c = ch;
while(ch > '' || ch < '')c = ch, ch = getchar();
while(ch >= '' && ch <= '')x = x * + ch - '',ch = getchar();
if(c == '-')x = -x;
}
long long work[MAXN],num[MAXN][],tmp,n,m;bool b[ + ];
struct STNODE{
long long l,r,max,min,sum,ssum;
}stnode[(MAXN << )+ ];
void build(int o = , int l = , int r = m){
stnode[o].l = l;stnode[o].r = r;
if(l == r){
stnode[o].max = l;
stnode[o].min = l;
stnode[o].sum = num[l][];
stnode[o].ssum = num[l][];
return;
}
int mid = (l + r) >> ;
build(o << , l, mid);
build(o << | , mid + , r);
if(num[stnode[o << ].max][] > num[stnode[o << | ].max][])stnode[o].max = stnode[o << ].max;
else stnode[o].max = stnode[o << | ].max;
if(num[stnode[o << ].min][] < num[stnode[o << | ].min][]) stnode[o].min = stnode[o << ].min;
else stnode[o].min = stnode[o << | ].min;
stnode[o].sum = stnode[o << ].sum + stnode[o << | ].sum;
stnode[o].ssum = stnode[o << ].ssum + stnode[o << | ].ssum;
}
void cutoff(int p, int o = ){
int l = stnode[o].l;int r = stnode[o].r;
if(l == r && l == p){
stnode[o].ssum = stnode[o].sum = stnode[o].max = stnode[o].min = ;
return;
}
int mid = (l + r) >> ;
if(mid >= p) cutoff(p, o << );
else cutoff(p, o << | );
stnode[o].sum = ;
stnode[o].ssum = ;
stnode[o].sum = stnode[o << ].sum + stnode[o << | ].sum;
stnode[o].ssum = stnode[o << ].ssum + stnode[o << | ].ssum;
if(num[stnode[o << ].max][] > num[stnode[o << | ].max][]) stnode[o].max = stnode[o << ].max;
else stnode[o].max = stnode[o << | ].max;
if(stnode[o << ].min == && stnode[o << | ].min == ) stnode[o].min = ;
else if(stnode[o << ].min == ) stnode[o].min = stnode[o << | ].min;
else if(stnode[o << | ].min == ) stnode[o].min = stnode[o << ].min;
else {
if(num[stnode[o << ].min][] < num[stnode[o << | ].min][]) stnode[o].min = stnode[o << ].min;
else stnode[o].min = stnode[o << | ].min;
}
}
int query_max(int ll,int rr,int o = ){
int ans1 = ;int ans2 = ;
int l = stnode[o].l;int r = stnode[o].r;
if(l >= ll && r <= rr) return stnode[o].max;
int mid = (l + r) >> ;
if(mid >= ll) ans1 = query_max(ll, rr, o << );
if(mid < rr) ans2 = query_max(ll, rr, o << | );
if(ans1 == && ans2 == ) return ;
if(num[ans1][] > num[ans2][]) return ans1;
else return ans2;
}
int query_min(int ll,int rr,int o = ){
int ans1 = ;int ans2 = ;
int l = stnode[o].l;int r = stnode[o].r;
if(l >= ll && r <= rr) return stnode[o].min;
int mid = (l + r) >> ;
if(mid >= ll) ans1 = query_min(ll, rr, o << );
if(mid < rr) ans2 = query_min(ll, rr, o << | );
if(ans1 == && ans2 == ) return ;
else if(ans1 == ) return ans2;
else if(ans2 == ) return ans1;
else {
if(num[ans1][] < num[ans2][]) return ans1;
else return ans2;
}
}
int main(){
read(tmp);
while(tmp != -){
n ++;
if(tmp == ){m ++;read(num[m][]);read(num[m][]);}
else if(tmp == ) work[n] = ;
else work[n] = ;
read(tmp);
}
if(m >= ) build();
int j = ;int len = ;
for(int i = ;i <= n;i ++){
if(work[i] == && len < j){
int a = query_max(, j);
cutoff(a);
b[num[a][]] = false;
len ++;
}
else if(work[i] == && len < j){
int a = query_min(, j);
cutoff(a);
b[num[a][]] = false;
len ++;
}
else if(!work[i]){
j ++;
if(!b[num[j][]]) b[num[j][]] = true;
else cutoff(j);
}
}
printf("%lld %lld", stnode[].sum, stnode[].ssum);
return ;
}
洛谷P2073 送花 [2017年6月计划 线段树01]的更多相关文章
- 洛谷P2835 刻录光盘 [2017年6月计划 强连通分量02]
P2835 刻录光盘 题目描述 在JSOI2005夏令营快要结束的时候,很多营员提出来要把整个夏令营期间的资料刻录成一张光盘给大家,以便大家回去后继续学习.组委会觉得这个主意不错!可是组委会一时没有足 ...
- 洛谷P1621 集合 [2017年6月计划 数论13]
P1621 集合 题目描述 现在给你一些连续的整数,它们是从A到B的整数.一开始每个整数都属于各自的集合,然后你需要进行一下的操作: 每次选择两个属于不同集合的整数,如果这两个整数拥有大于等于P的公共 ...
- 洛谷P1774 最接近神的人_NOI导刊2010提高(02) [2017年6月计划 线段树03]
P1774 最接近神的人_NOI导刊2010提高(02) 题目描述 破解了符文之语,小FF开启了通往地下的道路.当他走到最底层时,发现正前方有一扇巨石门,门上雕刻着一幅古代人进行某种活动的图案.而石门 ...
- 洛谷P1978 集合 [2017年6月计划 数论08]
P1978 集合 题目描述 集合是数学中的一个概念,用通俗的话来讲就是:一大堆数在一起就构成了集合.集合有如 下的特性: •无序性:任一个集合中,每个元素的地位都是相同的,元素之间是无序的. •互异性 ...
- 洛谷P1062 数列 [2017年6月计划 数论03]
P1062 数列 题目描述 给定一个正整数k(3≤k≤15),把所有k的方幂及所有有限个互不相等的k的方幂之和构成一个递增的序列,例如,当k=3时,这个序列是: 1,3,4,9,10,12,13,… ...
- 洛谷P2826 [USACO08NOV]光开关Light Switching [2017年6月计划 线段树02]
P2826 [USACO08NOV]光开关Light Switching 题目描述 Farmer John tries to keep the cows sharp by letting them p ...
- 洛谷P1650 赛马[2017年5月计划 清北学堂51精英班Day1]
P1650 赛马 题目描述 我国历史上有个著名的故事: 那是在2300年以前.齐国的大将军田忌喜欢赛马.他经常和齐王赛马.他和齐王都有三匹马:常规马,上级马,超级马.一共赛三局,每局的胜者可以从负者这 ...
- 洛谷P2258 子矩阵[2017年5月计划 清北学堂51精英班Day1]
题目描述 给出如下定义: 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵. 例如,下面左图中选取第2.4行和第2.4.5列交叉位置的元素 ...
- 洛谷P2196 挖地雷 [2017年4月计划 动态规划13]
P2196 挖地雷 题目背景 NOIp1996提高组第三题 题目描述 在一个地图上有N个地窖(N<=20),每个地窖中埋有一定数量的地雷.同时,给出地窖之间的连接路径.当地窖及其连接的数据给出之 ...
随机推荐
- VUE下echarts宽度响应式
window.addEventListener("resize", () => { myChart2.resize();});
- PHP函数高级(二)
PHP函数基础:https://www.cnblogs.com/lxwphp/p/9867840.html 1.函数分类: 定义:完成某些功能的代码段 系统函数:字符串,数组,数字,日期时间 自定 ...
- nginx 安装配置信息
#user nobody;worker_processes 1; #error_log logs/error.log;#error_log logs/error.log notice;#error_l ...
- iOS之CGcontext.h方法和属性简介
/* CoreGraphics - CGContext.h Copyright (c) 2000-2012 Apple Inc. All rights reserved. */ #ifndef CGC ...
- Docker系列(十三):Kubernetes Service的负载均衡和网络路由的秘密
Kubernetes Service设计分析 什么是单体程序?所有的模块都在一个进程中 微服务,每一个服务是一个进程的模式 kubernetes中的service其实只是一个概念,是一组相同lable ...
- 转:shell笔试题
源地址:http://blog.csdn.net/zcsylj/article/details/6799632 1.用Shell编程,判断一文件是不是块或字符设备文件,如果是将其拷贝到 /dev 目录 ...
- linux最基础最常用的命令快速手记 — 让手指跟上思考的速度(三)
这一篇作为姐妹篇的第三篇,废话不多说,我觉得这个比mysql的还要重要,为什么,一旦你摊上linux 敲键盘输入命令简直是要飞的速度,不断的卡壳查命令,效率太低了,而且非常严重的影响思绪,思绪! 某些 ...
- OSG实现正八面体剖分成球
#include<Windows.h> #include<osg/Node> #include<osg/Geode> #include<osg/Group&g ...
- Python中的HTMLParser、cookielib抓取和解析网页、从HTML文档中提取链接、图像、文本、Cookies(二)
对搜索引擎.文件索引.文档转换.数据检索.站点备份或迁移等应用程序来说,经常用到对网页(即HTML文件)的解析处理.事实上,通过 Python语言提供的各种模块,我们无需借助Web服务器或者Web浏览 ...
- 【DM642学习笔记四】flash烧写过程——错误记录…
(欢迎批评指正) 一,打开.cdd配置文件时出错: 解决:在FlashBurn配置窗口中,Conversion Cmd一栏可不用管: 菜单Program—Download FBTC,load ...