送花

题目背景

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

题目描述

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

思路

splay

代码实现

 1 #include<cstdio>
 2 const int maxn=3e5;
 3 int hd,rt;
 4 int a,w,c,tw,tc;
 5 int t[maxn],f[maxn],d[maxn],s[maxn][2];
 6 void rot(int x){
 7     int y=f[x],z=f[y],l,r;
 8     l=s[y][0]==x?0:1,r=l^1;
 9     if(y==rt) rt=x;
10     else{
11         if(s[z][0]==y) s[z][0]=x;
12         else s[z][1]=x;
13     }
14     f[x]=z,f[y]=x,f[s[x][r]]=y;
15     s[y][l]=s[x][r],s[x][r]=y;
16 }
17 void splay(int x){while(x!=rt) rot(x);}
18 void ins(int x,int w,int k,int fa){
19     if(!rt){rt=++hd,t[rt]=x,d[rt]=w;return;}
20     while(k){
21         fa=k;
22         if(x<t[k]) k=s[k][0];
23         else if(x>t[k]) k=s[k][1];
24         else if(x==t[k]) return;
25     }
26     if(x<t[fa]) k=s[fa][0]=++hd;
27     else k=s[fa][1]=++hd;
28     t[k]=x,d[k]=w,f[k]=fa;
29     splay(k);
30 }
31 int in(int k,int fa){
32     if(!k) return fa;
33     return in(s[k][0],k);
34 }
35 int ax(int k,int fa){
36     if(!k) return fa;
37     return ax(s[k][1],k);
38 }
39 void del(int x){
40     if(!x) return;
41     splay(x);
42     if(s[x][0]&&s[x][1]){
43         int k=s[x][1];rt=k;
44         while(s[k][0]) k=s[k][0];
45         s[k][0]=s[x][0],f[s[x][0]]=k;
46     }
47     else rt=s[x][0]+s[x][1];
48     f[rt]=0;
49 }
50 void tot(int k){
51     if(!k) return;
52     tc+=t[k],tw+=d[k];
53     tot(s[k][0]);
54     tot(s[k][1]);
55 }
56 int main(){
57     while(1){
58         scanf("%d",&a);
59         if(a==1){
60             scanf("%d%d",&w,&c);
61             ins(c,w,rt,0);
62         }
63         if(a==2) del(ax(rt,0));
64         if(a==3) del(in(rt,0));
65         if(a==-1){
66             tot(rt);
67             printf("%d %d
",tw,tc);
68             return 0;
69         }
70     }
71 }
原文地址:https://www.cnblogs.com/J-william/p/6941917.html