BZOJ1691: [Usaco2007 Dec]挑剔的美食家

经历一天学一课的期末考试后 队友让我写写题找找手感....

这题....很裸 一眼multiset...但是教主的备注是splay 那就正好练手感呗...写了一个假贪心...太菜了....

题解:考虑到对于草和奶牛 按照新鲜度从大到小排序 对于每头奶牛找到当前的新鲜度里面最小的价格就ok了  对于每个奶牛操作前 将新鲜度大于等于他的鲜草加入到splay中 查询即可

#include <bits/stdc++.h>
const int MAXN=2e5+10;
const int inf=1e9+21;
#define ll long long
using namespace std;
int ch[MAXN][2],size[MAXN],key[MAXN],root,pre[MAXN],p[MAXN];
int S[MAXN],tot;
int cnt;
void Treavel(int x)
{
    if(x)
    {
        Treavel(ch[x][0]);
        printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d,key=%2d\n",x,ch[x][0],ch[x][1],pre[x],size[x],key[x]);
        Treavel(ch[x][1]);
    }
}
void debug(int rp)
{
    printf("root:%d\n",rp);
    Treavel(rp);
}
ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}
typedef struct Splay{
    int maxx,pos,pos1;
    void newnode(int &x,int y,int vul,int t){
	if(tot)x=S[tot--];
	else x=++cnt;
	p[x]=t;
	ch[x][0]=ch[x][1]=0;pre[x]=y;size[x]=1;key[x]=vul;
    }
    void inte(){
	newnode(root,0,-1*inf,0);
	newnode(ch[root][1],root,inf,0);
    }
    void up(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+1;}
    void rotate(int x,int kind){
	int y=pre[x];
	pre[ch[x][kind]]=y;ch[y][!kind]=ch[x][kind];
	if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x;
	pre[x]=pre[y];ch[x][kind]=y;pre[y]=x;
	up(y);up(x);
    }
    void splay(int x,int goal){
	while(pre[x]!=goal){
	    if(pre[pre[x]]==goal)rotate(x,ch[pre[x]][0]==x);
	    else{
		int y=pre[x];int kind=ch[pre[y]][0]==y;
		if(ch[y][kind]==x)rotate(x,!kind),rotate(x,kind);
		else rotate(y,kind),rotate(x,kind);
	    }
	}
	if(goal==0)root=x;
    }
    int find1(int x,int sz){
	if(sz==size[ch[x][0]]+1)return x;
	else if(sz<=size[ch[x][0]])return find1(ch[x][0],sz);
	else return find1(ch[x][1],sz-size[ch[x][0]]-1);
    }
    int find2(int x,int vul,int t){
	if(!x)return 0;
	if(vul==key[x]&&t==p[x])return x;
	else if(vul==key[x]&&t<p[x])return find2(ch[x][0],vul,t);
	else if(vul==key[x]&&t>p[x])return find2(ch[x][1],vul,t);
	else if(vul<key[x])return find2(ch[x][0],vul,t);
	else return find2(ch[x][1],vul,t);
    }
    void destory(int x){
	if(!x)return ;
	splay(x,0);int sz=size[ch[x][0]];
	splay(find1(root,sz),0);
	splay(find1(root,sz+2),root);
	S[++tot]=ch[ch[root][1]][0];
	ch[ch[root][1]][0]=0;up(ch[root][1]);up(root);
    }
    void last_node(int x,int vul){
	if(!x)return ;
	if(key[x]<vul)last_node(ch[x][1],vul);
	else{
	    if(key[x]<maxx||(key[x]==maxx&&pos1>p[x]))maxx=key[x],pos=x,pos1=p[x];
	    last_node(ch[x][0],vul);
	}
    }
    void insert(int &x,int vul,int fa,int t){
	if(!x){newnode(x,fa,vul,t);return ;}
	if(key[x]>vul)insert(ch[x][0],vul,x,t);
	else insert(ch[x][1],vul,x,t);
	up(x);
    }
}Splay;
int n,m;
typedef struct node{
    int x,y;
    friend bool operator<(node aa,node bb){return aa.y>bb.y;}
}node;
bool cmp(node aa,node bb){
    return aa.y>bb.y;
}
node a[MAXN],b[MAXN];
int main(){
    n=read();m=read();
    for(int i=1;i<=n;i++)a[i].x=read(),a[i].y=read();
    for(int i=1;i<=m;i++)b[i].x=read(),b[i].y=read();
    if(n>m){puts("-1");return 0;}
    sort(a+1,a+n+1,cmp);sort(b+1,b+1+m);
    Splay T;T.inte();
    //for(int i=1;i<=m;i++){T.insert(root,b[i].x,0,i);T.splay(cnt,0);}
    int l=1;ll ans=0;
    for(int i=1;i<=n;i++){
	while(l<=m&&b[l].y>=a[i].y){T.insert(root,b[l].x,0,l);l++;}
//	debug(root);
	//if(l>m){puts("-1");return 0;}
	T.maxx=inf;T.pos1=inf;T.last_node(root,a[i].x);
	if(T.maxx==inf){puts("-1");return 0;}
	ans+=T.maxx;T.destory(T.pos);
//	debug(root);
    }
    printf("%lld\n",ans);
    return 0;
}

 

1691: [Usaco2007 Dec]挑剔的美食家

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 1014  Solved: 525
[Submit][Status][Discuss]

Description

与很多奶牛一样,Farmer John那群养尊处优的奶牛们对食物越来越挑剔,随便拿堆草就能打发她们午饭的日子自然是一去不返了。现在,Farmer John不得不去牧草专供商那里购买大量美味多汁的牧草,来满足他那N(1 <= N <= 100,000)头挑剔的奶牛。 所有奶牛都对FJ提出了她对牧草的要求:第i头奶牛要求她的食物每份的价钱不低于A_i(1 <= A_i <= 1,000,000,000),并且鲜嫩程度不能低于B_i(1 <= B_i <= 1,000,000,000)。商店里供应M(1 <= M <= 100,000)种不同的牧草,第i 种牧草的定价为C_i(1 <= C_i <= 1,000,000,000),鲜嫩程度为D_i (1 <= D_i <= 1,000,000,000)。 为了显示她们的与众不同,每头奶牛都要求她的食物是独一无二的,也就是说,没有哪两头奶牛会选择同一种食物。 Farmer John想知道,为了让所有奶牛满意,他最少得在购买食物上花多少钱。

Input

* 第1行: 2个用空格隔开的整数:N 和 M

* 第2..N+1行: 第i+1行包含2个用空格隔开的整数:A_i、B_i * 第N+2..N+M+1行: 第j+N+1行包含2个用空格隔开的整数:C_i、D_i

Output

* 第1行: 输出1个整数,表示使所有奶牛满意的最小花费。如果无论如何都无法 满足所有奶牛的需求,输出-1

Sample Input

4 7
1 1
2 3
1 4
4 2
3 2
2 1
4 3
5 2
5 4
2 6
4 4

Sample Output

12

输出说明:

给奶牛1吃价钱为2的2号牧草,奶牛2吃价钱为4的3号牧草,奶牛3分到价钱
为2的6号牧草,奶牛4选择价钱为4的7号牧草,这种分配方案的总花费是12,为
所有方案中花费最少的。

posted @ 2018-07-20 18:11  wang9897  阅读(132)  评论(0编辑  收藏  举报