洛谷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),每个地窖中埋有一定数量的地雷.同时,给出地窖之间的连接路径.当地窖及其连接的数据给出之 ...
随机推荐
- HTTP的九种请求方法
HTTP1.0定义了三种请求方法:GET.POST.HEAD HTTP1.1定义了六种请求方法:PUT.DELETE.PATCH.OPTIONS.CONNECT.TRACE 1.get 请求指定页面的 ...
- IOS学习笔记56-IOS7状态栏适配方法一
近期由于IOS7的发布,所以应用的适配潮可谓是都搞的锣鼓喧天,甚是热闹,因此呢,因适配IOS7而产生的问题也是铺天盖地的卷来,所以了,我也从简单的状态栏适配开始,先研究了下关于状态栏的适配,特总结如下 ...
- Installer - win10安装及卸载SQL Server2008数据库
一.数据库安装环境 操作系统:win10 SQL server:SQL server 2008 R2 二.全新数据库安装 1.安装扩展文件 双击安装文件,弹出如下窗体: ...
- Docker系列(十):Kubernetes集群入门
kubenetes安装 官网:https://github.com/kubernetes/kubernetes/blob/release-1.0/docs/getting-started- guide ...
- JavaScript事件(随笔)
1. Javascript事件介绍 JavaScript中的事件和现实生活中的事件类似,现实生活中发生的一些事情,例如:交通事件,当这些事情发生时,我们需要提供处理方案: 在JavaScript中事件 ...
- python 筛选序列中的元素
列表生成式 a = [1, 2, 3, 4, -1, -2] b = [i for i in a if a > 0] 如果数据量很大,会产生一个庞大的结果.这时可以用生成器表达式: b = (i ...
- MyEclipse 最常用实用快捷键
- Leetcode959. Regions Cut By Slashes由斜杠划分区域
在由 1 x 1 方格组成的 N x N 网格 grid 中,每个 1 x 1 方块由 /.\ 或空格构成.这些字符会将方块划分为一些共边的区域. (请注意,反斜杠字符是转义的,因此 \ 用 &quo ...
- goland破解
PyCharm是由著名的JetBrains公司所打造的一款功能强大的Python IDE,它具有一般IDE都具备的功能,并且使用起来非常方便好用.最近需求PyCharm激活码的网友非常多,小编就在这里 ...
- Odoo QWeb
1.web 模块 注意,OpenERP 模块中 web 部分用到的所有文件必须被放置在模块内的 static 文件夹里.这是强制性的,出于安全考虑. 事实上,我们创建的文件夹 CSS,JS 和 XML ...