zoukankan      html  css  js  c++  java
  • [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
    ",beauty,price);
    	return 0;
    }
    
    
  • 相关阅读:
    linux之awk命令
    HDU 2097 Sky数 进制转换
    HDU 2077 汉诺塔IV
    HDU 2094 产生冠军 dfs加map容器
    HDU 2073 叠框
    HDU 2083 简易版之最短距离
    HDU 2063 过山车 二分匹配
    天梯 1014 装箱问题
    天梯 1214 线段覆盖
    天梯 1098 均分纸牌
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8167931.html
Copyright © 2011-2022 走看看