题意
poj3622
有n头牛,m中养料,每种养料有两个值
分别表示价钱和分量吧(我发誓他写的不是分量..但是…>_<…俗话说要体谅英语不好的人) 然后每头牛都需要吃价值大于x,分量大于y的养料。问这些牛都吃满意了所需最小价钱
题解
给养料、牛排序,按照分量越大价钱越大越靠前排
然后对于每头牛,把养料分量大约它所需要的加入平横树里
然后它所花费的最小价钱就是它所需的最小价钱的后继
代码
#include <cstdio>
#include <algorithm>
using namespace std;
#define N 110000
#define inf 0x7fffffff
struct node{int x,y;}a[N],b[N];
int n,m,tot=0,root=0,pre,succ,ans,v[N],ch[N][2],fa[N],num[N];
long long sum=0;
bool cmp(node x,node y){return x.y>y.y || (x.y==y.y && x.x>y.x);}
int read(){
int f=1,x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline void rotate(int &x){
int y=fa[x],z=fa[y],t=ch[y][0]==x;
if(z) ch[z][ch[z][1]==y]=x;
else root=x;
fa[x]=z;fa[y]=x;fa[ch[x][t]]=y;
ch[y][t^1]=ch[x][t];ch[x][t]=y;
}
inline void splay(int x,int &rt){
while(x!=rt){
int y=fa[x];
if(y==rt){rotate(x);return;}
if(ch[y][0]==x^ch[fa[y]][0]==y) rotate(x);
else rotate(y);rotate(x);
}
}
inline void insert(int &p,int x,int f){
if(!p){
p=++tot;v[p]=x;num[p]=1;ch[p][0]=ch[p][1]=0;fa[p]=f;
splay(p,root);return;
}if(x==v[p]) num[p]++;
else if(x<v[p]) insert(ch[p][0],x,p);
else insert(ch[p][1],x,p);
}
inline void query(int p,int x){
if(v[p]>=x){
succ=p;
if(ch[p][0]) query(ch[p][0],x);
}else if(ch[p][1]) query(ch[p][1],x);
}
inline void del(int p){
if(num[p]>1){num[p]--;return;}
while(ch[p][0]*ch[p][1]) splay(ch[p][0],p);
while(ch[p][0]) splay(ch[p][0],p);
while(ch[p][1]) splay(ch[p][1],p);
if(fa[p]) ch[fa[p]][ch[fa[p]][1]==p]=0;
else root=0;
}
int main(){
freopen("poj3622.in","r",stdin);
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();
sort(b+1,b+1+m,cmp);sort(a+1,a+n+1,cmp);
int k=1;
for(int i=1;i<=n;i++){
while(b[k].y>=a[i].y) insert(root,b[k++].x,0);
succ=0;query(root,a[i].x);
if(!succ){printf("-1\n");return 0;}
sum=(long long)v[succ]+sum;
del(succ);
}printf("%lld\n",sum);
return 0;
}