赞
踩
小明准备给小红送一束花,以表达他对小红的爱意。他在花店看中了一些花,准备用它们包成花束。
这些花都很漂亮,每朵花有一个美丽值 W W W,价格为 C C C。
小明一开始有一个空的花束,他不断地向里面添加花。他有以下几种操作:
当花束为空时,忽略操作 2 2 2 和 3 3 3。
请你写一个程序,计算出开始包装花束时,花束中所有花的美丽值的总和,以及小明需要为花束付出的总价格。
若干行,每行一个操作,以 − 1 -1 −1 结束。
一行,两个空格隔开的正整数表示开始包装花束时,花束中所有花的美丽值的总和。以及小明需要为花束付出的总价格。
1 1 1
1 2 5
2
1 3 3
3
1 5 2
-1
8 5
设操作数为 m m m。
#include<bits/stdc++.h> using namespace std; const int N=1e6+10; typedef long long ll; int k,pp,meimei; struct stu{ int p,mei; }tree[N*4]; void pushup(int u){ tree[u].p=tree[u<<1].p+tree[u<<1|1].p;//左右两子段的区间和(总价格和总美丽值)相加反馈给顶部 tree[u].mei=tree[u<<1].mei+tree[u<<1|1].mei; } void update(int l,int r,int u,int p,int mei){//插入一朵价格为p,美丽值为mei的花 if(l==r){//到达叶子结点 if(tree[u].p==p) return;//如果已经有一朵价格为p的花了,则不能加入该花 tree[u].p=p;//否则更新该点信息 tree[u].mei=mei; } else{//未到叶子结点继续折半查找 int mid=(l+r)>>1; if(p<=mid) update(l,mid,u<<1,p,mei);//查找左子树 else update(mid+1,r,u<<1|1,p,mei);//查找右子树 pushup(u);//对顶部更新 } } void remove(int l,int r,int u,int sign){//删除一朵花 if(l==r) tree[u]={0,0};//找到该点清空删除 else{ int mid=(l+r)>>1; if(sign){//sign=1是删除最大值 if(!tree[u<<1|1].p) remove(l,mid,u<<1,sign); //右区间为空则找左区间 else remove(mid+1,r,u<<1|1,sign); //否则就找右区间 } else{//sign=0是删除最小值 if(!tree[u<<1].p) remove(mid+1,r,u<<1|1,sign); //左区间为空则找右区间 else remove(l,mid,u<<1,sign); //否则就找左区间 } pushup(u);//对顶部更新 } } int main(){ while(scanf("%d",&k)!=EOF){ if(k==-1) break; if(k==1){ scanf("%d %d",&meimei,&pp); update(1,N,1,pp,meimei); } else if(tree[1].p==0) continue; else if(k==2) remove(1,N,1,1); else remove(1,N,1,0); } cout<<tree[1].mei<<" "<<tree[1].p<<endl; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。