[Luogu2073]送花

题面
题目背景
小明准备给小红送一束花,以表达他对小红的爱意。他在花店看中了一些花,准备用它们包成花束。
题目描述
这些花都很漂亮,每朵花有一个美丽值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傻逼板子题吗?
注意题面操作2和3是反的呵
然后就是板子了
然而我还是WA了一次

code

#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
const int N = 100005;
int fa[N],ls[N],rs[N],val[N],W[N],root,tot,opt;
ll price,beauty;
void R_rotate(int x)
{
	int y=fa[x],z=fa[y];
	ls[y]=rs[x];
	if (rs[x]) fa[rs[x]]=y;
	fa[x]=z;
	if (z) if (y==ls[z]) ls[z]=x;else rs[z]=x;
	rs[x]=y;fa[y]=x;
}
void L_rotate(int x)
{
	int y=fa[x],z=fa[y];
	rs[y]=ls[x];
	if (ls[x]) fa[ls[x]]=y;
	fa[x]=z;
	if (z) if (y==ls[z]) ls[z]=x;else rs[z]=x;
	ls[x]=y;fa[y]=x;
}
void splay(int x)
{
	while (fa[x])
	{
		int y=fa[x],z=fa[y];
		if (!z)
			if (x==ls[y]) R_rotate(x);
			else L_rotate(x);
		else
			if (y==ls[z])
				if (x==ls[y]) R_rotate(y),R_rotate(x);
				else L_rotate(x),R_rotate(x);
			else
				if (x==ls[y]) R_rotate(x),L_rotate(x);
				else L_rotate(y),L_rotate(x);
	}
	root=x;
}
void Insert()
{
	int x=root,v,w;scanf("%d %d",&w,&v);
	if (!root)
	{
		root=++tot;
		val[root]=v;W[root]=w;
		return;
	}
	while (1)
	{
		if (v<val[x])
		{
			if (!ls[x])
			{
				ls[x]=++tot;
				val[tot]=v;W[tot]=w;
				fa[tot]=x;
				splay(tot);
				return;
			}
			x=ls[x];
		}
		else if (v>val[x])
		{
			if (!rs[x])
			{
				rs[x]=++tot;
				val[tot]=v;W[tot]=w;
				fa[tot]=x;
				splay(tot);
				return;
			}
			x=rs[x];
		}
		else if (v==val[x]) return;
	}
}
void Del_Max()
{
	int x=root;
	if (!rs[x])
	{
		fa[root=ls[x]]=0;
		return;
	}
	while (rs[x]) x=rs[x];
	rs[fa[x]]=ls[x];
	if (ls[x]) fa[ls[x]]=fa[x];
}
void Del_Min()
{
	int x=root;
	if (!ls[x])
	{
		fa[root=rs[x]]=0;
		return;
	}
	while (ls[x]) x=ls[x];
	ls[fa[x]]=rs[x];
	if (rs[x]) fa[rs[x]]=fa[x];
}
void dfs(int x)
{
	price+=val[x];beauty+=W[x];
	if (ls[x]) dfs(ls[x]);
	if (rs[x]) dfs(rs[x]);
}
int main()
{
	while (1)
	{
		scanf("%d",&opt);
		if (opt==-1) break;
		if (opt==1) Insert();
		if (opt==2) Del_Max();
		if (opt==3) Del_Min();
	}
	dfs(root);
	printf("%lld %lld\n",beauty,price);
	return 0;
}

posted @ 2018-01-01 17:08  租酥雨  阅读(204)  评论(0编辑  收藏  举报