Description
机房里有M台电脑排成一排,第i台电脑的坐标是正整数i。
现在有N个OIer进入了机房,每个OIer需要一台电脑来学tui习ji,同时每个OIer对自己电脑所处的坐标范围有一个要求区间。第i个OIer希望自己的电脑的位置≤Li或≥Ri。自然,一台电脑只能给一个OIer使用,不然会发生友♂好的跤♂流
显然,有可能这个机房无法满足所有OIer的需求。这时老师就会在机房中增加电脑。增加的电脑可以位于任意的实数位置。你需要帮老师计算一下,老师最少加几台电脑,才可以满足所有OIer的需求?
Input
第一行两个整数N,M
接下来N行,每行两个整数Li,Ri
Output
输出最小需要增加的电脑数量
Solution
贪心。
将询问按l,r作为第一、二关键字从小到大排序。
优先插进左端点,并恰好插满左端点(不能大于查询的l)
占据左边的端点的询问的丢进小根堆的优先队列。
记录一个tot表示用了1到tot号电脑。
- 若tot小于 L i L_i Li,直接丢进优先队列。
- 若tot等于 L i L_i Li,将优先队列中右端点最小的弹出来扔到右边。
因为记录的是向右的标记(>=x)
最后从后往前ans=max(ans,后缀和-后面已有的电脑数)
Code
#include<bits/stdc++.h>
using namespace std;
struct data{
int l,r;
bool operator <(const data &v)const{
if(l!=v.l) return l<v.l;
return r<v.r;
}
}a[200010];
priority_queue<int>q;
int b[200010],n,m;
int main(){
int x,y,tot=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d%d",&a[i].l,&a[i].r);
for(int i=1;i<=m;i++) b[i]=-1;
sort(a+1,a+n+1);
for(int i=1;i<=n;i++){
//cout<<i<<" "<<a[i].l<<" "<<a[i].r<<" "<<q.size()<<endl;
if(a[i].l==0){
b[a[i].r]++;
continue;
}
if(a[i].l==tot){
int x=q.top();
q.pop();
//cout<<"kk"<<u.l<<" "<<u.r<<" "<<b[u.l]<<" "<<b[u.r]<<endl;
b[-x]++;
q.push(-a[i].r);
continue;
}
//cout<<"sss"<<a[i].l<<" "<<b[a[i].l]<<endl;
b[++tot]++;
q.push(-a[i].r);
}
int ans=0,sum=0;
for(int i=m+1;i>-1;i--){
sum+=b[i];
ans=max(ans,sum);
// cout<<b[i]<<endl;
}
printf("%d",ans);
}