挑剔的美食家
约翰的奶牛对食物越来越挑剔了。现在,商店有M 份牧草可供出售,奶
牛食量很大,每份牧草仅能供一头奶牛食用。第i 份牧草的价格为Pi,口感为
Qi。约翰一共有N 头奶牛,他要为每头奶牛订购一份牧草,第i 头奶牛要求
它的牧草价格不低于Ai,口感不低于Bi。请问,约翰应该如何为每头奶牛选
择牧草,才能让他花的钱最少?
输入格式
• 第一行:两个整数N 和M,1 ≤ N ≤ M ≤ 105
• 第二行到第N +1 行:第i+1 行有两个整数Ai 和Bi,1 ≤ Ai;Bi ≤ 109
• 第N + 2 行到第N + M + 1 行:第i + N + 1 行有两个整数Pi 和Qi,
1 ≤ Pi;Qi ≤ 109
输出格式
• 单个整数:表示在满足所有奶牛的要求下的最少总花费,如果不存在这种
方案,输出−1。
样例输入
4 7
1 1
2 3
1 4
4 2
3 2
2 1
4 3
5 2
5 4
2 6
4 4
样例输出
12
解
第一头牛吃第二份草,花2 元;
第二头牛吃第三份草,花4 元;第三
头牛吃第六份草,花2 元;第四头牛
约翰的奶牛对食物越来越挑剔了。现在,商店有M 份牧草可供出售,奶
牛食量很大,每份牧草仅能供一头奶牛食用。第i 份牧草的价格为Pi,口感为
Qi。约翰一共有N 头奶牛,他要为每头奶牛订购一份牧草,第i 头奶牛要求
它的牧草价格不低于Ai,口感不低于Bi。请问,约翰应该如何为每头奶牛选
择牧草,才能让他花的钱最少?
输入格式
• 第一行:两个整数N 和M,1 ≤ N ≤ M ≤ 105
• 第二行到第N +1 行:第i+1 行有两个整数Ai 和Bi,1 ≤ Ai;Bi ≤ 109
• 第N + 2 行到第N + M + 1 行:第i + N + 1 行有两个整数Pi 和Qi,
1 ≤ Pi;Qi ≤ 109
输出格式
• 单个整数:表示在满足所有奶牛的要求下的最少总花费,如果不存在这种
方案,输出−1。
样例输入
4 7
1 1
2 3
1 4
4 2
3 2
2 1
4 3
5 2
5 4
2 6
4 4
样例输出
12
解
第一头牛吃第二份草,花2 元;
第二头牛吃第三份草,花4 元;第三
头牛吃第六份草,花2 元;第四头牛
吃第七份草,花4 元
#include<cstdio>
#include<cstdlib>
const int maxn=100002;
const int maxm=100002;
int n,m,a[maxm],b[maxm],p[maxn],q[maxn];
int lc[maxn],rc[maxn],k[maxn],count[maxn],root,s,height[maxn];
long long ans;
int rightrot(int x);
int leftrot(int x);
int find(int key)
{
int u=root;
int c=0;
while(u!=0)
{
if(k[u]<=key)
{
c=u;
u=rc[u];
}
else
{
u=lc[u];
}
}
return c;
}
int ins(int u,int key)
{
if(u==0)
{
u=++s;
k[u]=key;
height[u]=rand();
}
else if(k[u]==key)
{
count[u]++;
}
else if(k[u]<key)
{
rc[u]=ins(rc[u],key);
if(height[u]<height[rc[u]])
{
u=leftrot(u);
}
}
else
{
lc[u]=ins(lc[u],key);
if(height[u]<height[lc[u]])
{
u=rightrot(u);
}
}
return u;
}
int leftrot(int x)
{
int y=rc[x];
rc[x]=lc[y];
lc[y]=x;
return y;
}
int rightrot(int x)
{
int y=lc[x];
lc[x]=rc[y];
rc[y]=x;
return y;
}
int pop(int u)
{
if(rc[u]==0)
return lc[u];
if(lc[u]==0)
return rc[u];
if(height[rc[u]]<height[lc[u]])
{
int x=rightrot(u);
rc[x]=pop(u);
return x;
}
else
{
int x=leftrot(u);
lc[x]=pop(u);
return x;
}
}
int del(int u,int key)
{
if(u!=0)
{
if(k[u]<key)
{
rc[u]=del(rc[u],key);
}
else if(k[u]>key)
{
lc[u]=del(lc[u],key);
}
else
{
if(count[u]!=0)
count[u]--;
else
u=pop(u);
}
}
return u;
}
void swap(int *a,int *b)
{
int tmp=*a;
*a=*b;
*b=tmp;
}
void sort(int l,int r,int a[],int b[])
{
int key=a[rand()%(r-l+1)+l];
int i=l,j=r;
while(i<=j)
{
while(a[i]<key)
i++;
while(a[j]>key)
j--;
if(i<=j)
{
swap(&a[i],&a[j]);
swap(&b[i],&b[j]);
i++;
j--;
}
}
if(l<j)
sort(l,j,a,b);
if(i<r)
sort(i,r,a,b);
}
int main()
{
srand(909978797);
freopen("gourmet.in","r",stdin);
freopen("gourmet.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i],&b[i]);
}
for(int i=1;i<=m;i++)
{
scanf("%d%d",&p[i],&q[i]);
}
sort(1,n,a,b);
sort(1,m,p,q);
int hp=1;
for(int i=1;i<=m;i++)
{
while(hp<=n&&a[hp]<=p[i])
{
root=ins(root,b[hp]);
hp++;
}
int u=find(q[i]);
if(u!=0)
{
ans+=p[i];
root=del(root,k[u]);
}
}
printf("%lld\n",ans);
fclose(stdin);
fclose(stdout);
return 0;
}