题目背景
小明准备给小红送一束花,以表达他对小红的爱意。他在花店看中了一些花,准备用它们包成花束。
题目描述
这些花都很漂亮,每朵花有一个美丽值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 }