poj3622 Gourmet Grazers (平衡树)

题意

poj3622
有n头牛,m中养料,每种养料有两个值 a i , b i 分别表示价钱和分量吧(我发誓他写的不是分量..但是…>_<…俗话说要体谅英语不好的人) 然后每头牛都需要吃价值大于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;
}

猜你喜欢

转载自blog.csdn.net/sunshiness_s/article/details/79646254