按價格講草和牛排序,維護一個以美味度爲關鍵字的平衡樹,不斷枚舉牧草,插入比牧草價值低的牛,之後用平衡樹選擇前驅並刪除。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
char ch=getchar();int f=0;
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') {f=f*10+(ch^48);ch=getchar();}
return f;
}
int ch[200005][2],w[200005],fa[200005];
struct data
{
int val;
int sum;
}a[100005],b[100005];
bool cmp(const data &x,const data &y)
{
if(x.val!=y.val)
return x.val<y.val;
return x.sum<y.sum;
}
int n,m,rt,t,cou,sz;
void rotate(int x,int &k)
{
int y=fa[x],z=fa[y],l,r;
if(ch[y][0]==x) l=0;else l=1;r=l^1;
if(y==k)
{
k=x;
}
else
{
if(ch[z][0]==y) ch[z][0]=x;
else ch[z][1]=x;
}
fa[x]=z,fa[y]=x,fa[ch[x][r]]=y;
ch[y][l]=ch[x][r];ch[x][r]=y;
}
void splay(int x,int &k)
{
int y,z;
while(x!=k)
{
y=fa[x];z=fa[y];
if(y!=k)
{
if(ch[y][0]==x^ch[z][0]==y) rotate(x,k);
else rotate(y,k);
}
rotate(x,k);
}
}
void insert(int &k,int x,int last)
{
if(!k)
{
k=++sz;
w[k]=x;
fa[k]=last;
splay(k,rt);
return;
}
if(x<=w[k]) insert(ch[k][0],x,k);
else insert(ch[k][1],x,k);
}
long long ans;
void ask_before(int x,int k)
{
if(!k) return;
if(w[k]<=x)
{
t=k;
ask_before(x,ch[k][1]);
}
else
ask_before(x,ch[k][0]);
}
void del(int x)
{
splay(x,rt);
if(!ch[x][0]) rt=ch[x][1];
else if(!ch[x][1]) rt=ch[x][0];
else
{
int k=ch[x][1];
while(ch[k][0])
k=ch[k][0];
ch[k][0]=ch[x][0];
fa[ch[x][0]]=k;
rt=ch[x][1];
}
fa[rt]=0;
return;
}
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++)
{
a[i].val=read();a[i].sum=read();
}
for(int i=1;i<=m;i++)
{
b[i].val=read();b[i].sum=read();
}
sort(a+1,a+n+1,cmp);
sort(b+1,b+m+1,cmp);
int now=1;
for(int i=1;i<=m;i++)
{
while(a[now].val<=b[i].val&&now<=n)
{
insert(rt,a[now].sum,0);
now++;
}
t=0;
ask_before(b[i].sum,rt);
if(t)
{
cou++;
ans+=b[i].val;
if(cou==n)
break;
del(t);
}
}
if(cou!=n)
puts("-1");
else printf("%lld",ans);
}