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 MBSubmit: 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
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,为
所有方案中花费最少的。