P2073 送花
Posted five20
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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。
Solution:
本题$c$保证只会出现一次且$c\leq 10^6$,于是我们以$c$为关键字,维护花费和优美度,构建一棵权值线段树。
对于$1$操作,我们直接查询$c$节点是否有值,有就直接返回,否则就赋值。
对于$2$操作,要删去最大值,则从完整区间开始,只要右子树有点或左子树无点则尽可能遍历右儿子,否则才遍历左儿子,将最后到达的叶子节点清$0$。
对于$3$操作,要删去最小值,则从完整区间开始,只要左子树有点则尽可能遍历左儿子,否则才遍历右儿子,将最后到达的叶子节点清$0$。
最后输出整个区间的总优美度和总花费就$OK$了。
代码:
1 // luogu-judger-enable-o2 2 #include<bits/stdc++.h> 3 #define il inline 4 #define ll long long 5 #define lson (l),(m),(rt<<1) 6 #define rson (m+1),(r),(rt<<1|1) 7 #define Max(a,b) ((a)>(b)?(a):(b)) 8 #define Min(a,b) ((a)>(b)?(b):(a)) 9 using namespace std; 10 const int N=1e6+7,inf=2147483647; 11 ll n,m,sum[N<<2],cost[N<<2],f,l=1,r=1e6,a; 12 il int gi(){ 13 int a=0;char x=getchar();bool f=0; 14 while((x<‘0‘||x>‘9‘)&&x!=‘-‘)x=getchar(); 15 if(x==‘-‘)x=getchar(),f=1; 16 while(x>=‘0‘&&x<=‘9‘)a=a*10+x-48,x=getchar(); 17 return f?-a:a; 18 } 19 il void pushup(int rt){ 20 cost[rt]=cost[rt<<1]+cost[rt<<1|1]; 21 sum[rt]=sum[rt<<1]+sum[rt<<1|1]; 22 } 23 il void update(int k,int d,int l,int r,int rt){ 24 if(l==k&&r==k){ 25 if(cost[rt])return; 26 sum[rt]=d,cost[rt]=k;return; 27 } 28 int m=l+r>>1; 29 if(k<=m)update(k,d,lson); 30 else update(k,d,rson); 31 pushup(rt); 32 } 33 il void del(int l,int r,int rt,bool f){ 34 if(l==r){sum[rt]=cost[rt]=0;return;} 35 int m=l+r>>1; 36 if(f&&cost[rt<<1]&&cost[rt<<1|1])del(rson,f); 37 else if(!cost[rt<<1])del(rson,f); 38 else del(lson,f); 39 pushup(rt); 40 } 41 int main(){ 42 int x,y; 43 f=gi(); 44 while(f!=-1){ 45 if(f==1){x=gi(),y=gi();update(y,x,l,r,1);} 46 if(f==2){del(l,r,1,1);} 47 if(f==3){del(l,r,1,0);} 48 f=gi(); 49 } 50 cout<<sum[1]<<‘ ‘<<cost[1]; 51 return 0; 52 }
以上是关于P2073 送花的主要内容,如果未能解决你的问题,请参考以下文章