poj3622 Gourmet Grazers(貪心+Treap)

【題解】

將牛和草分別按鮮嫩度從大到小排序 
然後將牛掃一遍:
對於第i頭牛,將鮮嫩度>=b[i]的草的價格加入平衡樹,找出價格>=a[i]的最小的草,計入答案並刪除之 

正確性分析:若i<j,則i與j的草交換後,答案不會更優 


【代碼】

#include<stdio.h>
#include<stdlib.h>
#define INF 2000000000
typedef long long LL;
int a[100005],b[100005],c[100005],d[100005];
LL ans=0;
int min(int a,int b)
{
	if(a<b) return a;
	return b;
}
void jh(int* a,int* b)
{
	int t=*a;
	*a=*b;
	*b=t;
}
struct Node
{
	Node* ch[2];
	int v,r;
	int cmp(int x) const
	{
		if(x==v) return -1;
		if(x<v) return 0;
		return 1;
	}
};
Node *root,*null;
void init()
{
	null=new Node();
	null->ch[0] = null->ch[1] = NULL;
	null->v=null->r=0;
	root=null;
}
void xz(Node* &o,int d)
{
	Node* k=o->ch[d^1];
	o->ch[d^1]=k->ch[d];
	k->ch[d]=o;
	o=k;
}
void tj(Node* &o,int x)
{
	int d=o->cmp(x);
	if(o==null)
	{
		o=new Node();
		o->ch[0]=o->ch[1]=null;
		o->v=x;
		o->r=rand();
		return;
	}
	if(d==-1) d=0;
	tj(o->ch[d],x);
	if( o->ch[d]->r < o->r ) xz(o,d^1);
}
int cx(Node* &o,int x)
{
	int d=o->cmp(x);
	if(o==null) return INF;
	if(d==-1) return o->v;
	if(d==1) return cx(o->ch[d],x);
	return min(o->v,cx(o->ch[d],x));
}
void sc(Node* &o,int x)
{
	int d=o->cmp(x);
	if(d==-1)
	{
		if(o->ch[0]==null) o=o->ch[1];
		else
		{
			if(o->ch[1]==null) o=o->ch[0];
			else
			{
				if( o->ch[0]->r < o->ch[1]->r ) d=0;
				else d=1;
				xz(o,d^1);
				sc(o->ch[d^1],x);
			}
		}
	}
	else sc(o->ch[d],x);
}
void kp(int a[],int b[],int low,int high)
{
	int i=low,j=high,mid=a[(i+j)/2];
	while(i<j)
	{
		while(a[i]>mid) i++;
		while(a[j]<mid) j--;
		if(i<=j)
		{
			jh(&a[i],&a[j]);
			jh(&b[i],&b[j]);
			i++;
			j--;
		}
	}
	if(j>low) kp(a,b,low,j);
	if(i<high) kp(a,b,i,high);
}
int main()
{
	srand(325);
	int n,m,i,j=1,t;
	init();
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++)
		scanf("%d%d",&a[i],&b[i]);
	for(i=1;i<=m;i++)
		scanf("%d%d",&c[i],&d[i]);
	kp(b,a,1,n);
	kp(d,c,1,m);
	for(i=1;i<=n;i++)
	{
		while(j<=m&&d[j]>=b[i])
		{
			tj(root,c[j]);
			j++;
		}
		t=cx(root,a[i]);
		if(t==INF) break;
		ans+=(LL)t;
		sc(root,t);
	}
	if(i>n) printf("%lld",ans);
	else printf("-1");
	return 0;
}


發佈了110 篇原創文章 · 獲贊 8 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章