zoukankan      html  css  js  c++  java
  • 【JZOJ1246】【洛谷P2869】美食的食草动物【平衡树】

    题目大意:

    题目链接:https://www.luogu.org/problem/P2869
    约翰的奶牛对食物越来越挑剔了。现在,商店有M 份牧草可供出售,奶牛食量很大,每份牧草仅能供一头奶牛食用。第i 份牧草的价格为Pi,口感为Qi。约翰一共有N 头奶牛,他要为每头奶牛订购一份牧草,第i 头奶牛要求它的牧草价格不低于Ai,口感不低于Bi。请问,约翰应该如何为每头奶牛选择牧草,才能让他花的钱最少?


    思路:

    我们按牧草口感这一维排序,另一维就是裸的求后继了。
    建立一棵平衡树,每次在可选的项中查找后继,选择后删除即可。


    代码:

    #include <queue>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    
    const int N=100010,Inf=2e9;
    int n,m,root=1;
    ll ans;
    priority_queue<int> q;
    
    struct WYCAKIOI
    {
    	int x,y;
    }a[N],b[N];
    
    bool cmp(WYCAKIOI x,WYCAKIOI y)
    {
    	return x.y>y.y;
    }
    
    struct Treenode
    {
    	int lc,rc,cnt,val,dat;
    };
    
    struct Treap
    {
    	Treenode t[N];
    	int tot;
    	
    	int New(int val)
    	{
    		t[++tot].val=val;
    		t[tot].dat=rand();
    		t[tot].cnt=1;
    		return tot;
    	}
    	
    	void build()
    	{
    		root=New(-Inf);
    		t[1].rc=New(Inf);
    	}
    	
    	void zig(int &x)
    	{
    		int y=t[x].lc;
    		t[x].lc=t[y].rc; t[y].rc=x; x=y;
    	}
    	
    	void zag(int &x)
    	{
    		int y=t[x].rc;
    		t[x].rc=t[y].lc; t[y].lc=x; x=y;
    	}
    	
    	void insert(int &x,int val)
    	{
    		if (!x)
    		{
    			x=New(val);
    			return;
    		}
    		if (t[x].val==val)
    		{
    			t[x].cnt++;
    			return;
    		}
    		if (val<t[x].val)
    		{
    			insert(t[x].lc,val);
    			if (t[x].dat<t[t[x].lc].dat) zig(x);
    		}
    		else
    		{
    			insert(t[x].rc,val);
    			if (t[x].dat<t[t[x].rc].dat) zag(x);
    		}
    	}
    	
    	void del(int &x,int val)
    	{
    		if (!x) return;
    		if (t[x].val==val)
    		{
    			if (t[x].cnt>1)
    			{
    				t[x].cnt--;
    				return;
    			}
    			if (t[x].lc || t[x].rc)
    			{
    				if (!t[x].lc || t[t[x].rc].dat>t[t[x].lc].dat)
    					zag(x),del(t[x].lc,val);
    				else
    					zig(x),del(t[x].rc,val);
    			}
    			else x=0;
    			return;
    		}
    		if (val<t[x].val) del(t[x].lc,val);
    			else del(t[x].rc,val);
    	}
    	
    	int next(int x,int val)
    	{
    		if (!x) return Inf;
    		if (t[x].val>=val) return min(t[x].val,next(t[x].lc,val));
    			else return next(t[x].rc,val);
    	}
    }Treap;
    
    int main()
    {
    	scanf("%d%d",&n,&m);
    	srand(n*m%1000007);
    	for (int i=1;i<=n;i++)
    		scanf("%d%d",&a[i].x,&a[i].y);
    	for (int i=1;i<=m;i++)
    		scanf("%d%d",&b[i].x,&b[i].y);
    	sort(a+1,a+1+n,cmp);
    	sort(b+1,b+1+m,cmp);
    	Treap.build();
    	for (int i=1,j=0;i<=n;i++)
    	{
    		for (;j<m && b[j+1].y>=a[i].y;j++)
    			Treap.insert(root,b[j+1].x);
    		int k=Treap.next(root,a[i].x);
    		if (k>=Inf) return !printf("-1");
    		Treap.del(root,k);
    		ans+=(ll)k;
    	}
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    《WF编程》系列之 承载工作流:跟踪服务 Tracking Service
    C#中隐藏(new)和方法重写(override)和重载(overload)的区别
    一套完整自定义工作流的实现
    工作流规范
    新宇面试题
    c# 多态性
    SQL Join连接详解
    Minix安装及配置指南(转载)
    游戏开发的学习资料汇总
    error LNK2019: 无法解析的外部符号 __vsnprintf 问题的解决方法
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11997997.html
Copyright © 2011-2022 走看看