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

以上。

 #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]的更多相关文章

  1. 洛谷P2835 刻录光盘 [2017年6月计划 强连通分量02]

    P2835 刻录光盘 题目描述 在JSOI2005夏令营快要结束的时候,很多营员提出来要把整个夏令营期间的资料刻录成一张光盘给大家,以便大家回去后继续学习.组委会觉得这个主意不错!可是组委会一时没有足 ...

  2. 洛谷P1621 集合 [2017年6月计划 数论13]

    P1621 集合 题目描述 现在给你一些连续的整数,它们是从A到B的整数.一开始每个整数都属于各自的集合,然后你需要进行一下的操作: 每次选择两个属于不同集合的整数,如果这两个整数拥有大于等于P的公共 ...

  3. 洛谷P1774 最接近神的人_NOI导刊2010提高(02) [2017年6月计划 线段树03]

    P1774 最接近神的人_NOI导刊2010提高(02) 题目描述 破解了符文之语,小FF开启了通往地下的道路.当他走到最底层时,发现正前方有一扇巨石门,门上雕刻着一幅古代人进行某种活动的图案.而石门 ...

  4. 洛谷P1978 集合 [2017年6月计划 数论08]

    P1978 集合 题目描述 集合是数学中的一个概念,用通俗的话来讲就是:一大堆数在一起就构成了集合.集合有如 下的特性: •无序性:任一个集合中,每个元素的地位都是相同的,元素之间是无序的. •互异性 ...

  5. 洛谷P1062 数列 [2017年6月计划 数论03]

    P1062 数列 题目描述 给定一个正整数k(3≤k≤15),把所有k的方幂及所有有限个互不相等的k的方幂之和构成一个递增的序列,例如,当k=3时,这个序列是: 1,3,4,9,10,12,13,… ...

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

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

  7. 洛谷P1650 赛马[2017年5月计划 清北学堂51精英班Day1]

    P1650 赛马 题目描述 我国历史上有个著名的故事: 那是在2300年以前.齐国的大将军田忌喜欢赛马.他经常和齐王赛马.他和齐王都有三匹马:常规马,上级马,超级马.一共赛三局,每局的胜者可以从负者这 ...

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

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

  9. 洛谷P2196 挖地雷 [2017年4月计划 动态规划13]

    P2196 挖地雷 题目背景 NOIp1996提高组第三题 题目描述 在一个地图上有N个地窖(N<=20),每个地窖中埋有一定数量的地雷.同时,给出地窖之间的连接路径.当地窖及其连接的数据给出之 ...

随机推荐

  1. ES6数组对象新增方法

    1. Array.from() Array.from方法用于将两类对象转为真正的数组:类数组的对象( array-like object )和可遍历( iterable )的对象(包括 ES6 新增的 ...

  2. TableView之表头、表尾,区头、区尾!

    一.UITableView的UITableViewStyle 样式分为UITableViewStylePlain和UITableViewStyleGrouped两种: plain样式下区头和区尾是悬浮 ...

  3. C++ 字符串、string、char *、char[]、const char*的转换和区别

    1.字符串 字符串本质就是一串字符,在C++中大家想到字符串往往第一反应是std::string(后面简称string) 字符串得从C语言说起,string其实是个类,C语言是没有class的,所以C ...

  4. Spring框架使用ByName自动注入同名问题剖析

    问题描述   我们在使用spring框架进行项目开发的时候,为了配置Bean的方便经常会使用到Spring当中的Autosire机制,Autowire根据注入规则的不同又可以分为==ByName==和 ...

  5. C# 判断当前请求是GET、还是POST ?

    方法一: HttpContext.Current.Request.RequestType == "POST"   //当前请求为:POST 方法二: if(Request.Serv ...

  6. mybatis和java一些知识记录

    <where> <if test="userName != null and userName != ''"> and user_name like con ...

  7. 使用 jQuery 设置 disabled 属性与移除 disabled 属性

    表单中readOnly和disabled的区别:Readonly只针对input(text/ password)和textarea有效,而disabled对于所有的表单元素都有效,包括select,r ...

  8. Luogu P4933 大师(dp)

    P4933 大师 题意 题目背景 建筑大师最近在跟着数学大师ljt12138学数学,今天他学了等差数列,ljt12138决定给他留一道练习题. 题目描述 ljt12138首先建了\(n\)个特斯拉电磁 ...

  9. LUOGU P3178 [HAOI2015]树上操作

    传送门 解题思路 树链剖分裸题,线段树维护. 代码 #include<iostream> #include<cstdio> #include<cstring> #d ...

  10. Vue.nextTick()的介绍和使用场景

    每次都很好奇这个干嘛的,然后百度之后还是不明白.今天就彻彻底底好好的弄明白这是干嘛的!! 首先看一下vue文档 nextTick(),是将回调函数延迟在下一次DOM更新数据后调用,简单的理解是:当数据 ...